56 WORD Commute(WORD *fleft, WORD *fright)
58 if ( *fleft >= GAMMA && *fleft <= GAMMASEVEN
59 && *fright >= GAMMA && *fright <= GAMMASEVEN ) {
60 if ( fleft[FUNHEAD] < AM.OffsetIndex && fleft[FUNHEAD] > fright[FUNHEAD] )
81 WORD Normalize(
PHEAD WORD *term)
87 WORD *t, *m, *r, i, j, k, l, nsym, *ss, *tt, *u;
89 WORD *stop, *to = 0, *from = 0;
95 WORD psym[7*NORMSIZE],*ppsym;
96 WORD pvec[NORMSIZE],*ppvec,nvec;
97 WORD pdot[3*NORMSIZE],*ppdot,ndot;
98 WORD pdel[2*NORMSIZE],*ppdel,ndel;
99 WORD pind[NORMSIZE],nind;
100 WORD *peps[NORMSIZE/3],neps;
101 WORD *pden[NORMSIZE/3],nden;
102 WORD *pcom[NORMSIZE],ncom;
103 WORD *pnco[NORMSIZE],nnco;
104 WORD *pcon[2*NORMSIZE],ncon;
106 WORD *lnum=AT.n_llnum+1,nnum;
107 WORD *termout, oldtoprhs = 0, subtype;
108 WORD ReplaceType, didcontr, regval = 0;
111 CBUF *C = cbuf+AT.ebufnum;
112 WORD *ANsc = 0, *ANsm = 0, *ANsr = 0;
113 LONG oldcpointer = 0;
127 if ( !*t )
return(regval);
135 termout = AT.WorkPointer;
136 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
137 fillsetexp = termout+1;
146 nsym = nvec = ndot = ndel = neps = nden =
147 nind = ncom = nnco = ncon = 0;
166 if ( *t <= DENOMINATORSYMBOL && *t >= COEFFSYMBOL ) {
172 if ( AN.cTerm ) m = AN.cTerm;
175 ncoef = REDLENG(ncoef);
176 if ( *t == COEFFSYMBOL ) {
178 nnum = REDLENG(m[-1]);
182 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)m,nnum,
183 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
189 if ( DivRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)m,nnum,
190 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
198 if ( *t == NUMERATORSYMBOL ) { m -= nnum + 1; }
200 while ( *m == 0 && nnum > 1 ) { m--; nnum--; }
202 if ( i < 0 && *t == NUMERATORSYMBOL ) nnum = -nnum;
206 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)m,nnum) )
213 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)m,nnum) )
219 ncoef = INCLENG(ncoef);
223 else if ( *t == DIMENSIONSYMBOL ) {
224 if ( AN.cTerm ) m = AN.cTerm;
226 k = DimensionTerm(m);
227 if ( k == 0 )
goto NormZero;
228 if ( k == MAXPOSITIVE ) {
229 MLOCK(ErrorMessageLock);
230 MesPrint(
"Dimension_ is undefined in term %t");
231 MUNLOCK(ErrorMessageLock);
234 if ( k == -MAXPOSITIVE ) {
235 MLOCK(ErrorMessageLock);
236 MesPrint(
"Dimension_ out of range in term %t");
237 MUNLOCK(ErrorMessageLock);
240 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
241 else { *((UWORD *)lnum) = -k; nnum = -1; }
242 ncoef = REDLENG(ncoef);
243 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
244 ncoef = INCLENG(ncoef);
248 if ( ( *t >= MAXPOWER && *t < 2*MAXPOWER )
249 || ( *t < -MAXPOWER && *t > -2*MAXPOWER ) ) {
256 if ( t[1] & 1 ) ncoef = -ncoef;
258 else if ( *t == MAXPOWER ) {
259 if ( t[1] > 0 )
goto NormZero;
267 if ( t[1] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[1]))) )
269 ncoef = REDLENG(ncoef);
271 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
274 else if ( t[1] > 0 ) {
275 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
278 ncoef = INCLENG(ncoef);
285 if ( ( *t <= NumSymbols && *t > -MAXPOWER )
286 && ( symbols[*t].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
287 if ( t[1] <= 2*MAXPOWER && t[1] >= -2*MAXPOWER ) {
288 t[1] %= symbols[*t].maxpower;
289 if ( t[1] < 0 ) t[1] += symbols[*t].maxpower;
290 if ( ( symbols[*t].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
291 if ( ( ( symbols[*t].maxpower & 1 ) == 0 ) &&
292 ( t[1] >= symbols[*t].maxpower/2 ) ) {
293 t[1] -= symbols[*t].maxpower/2; ncoef = -ncoef;
296 if ( t[1] == 0 ) { t += 2;
goto NextSymbol; }
305 if ( *t > 2*MAXPOWER || *t < -2*MAXPOWER
306 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
307 MLOCK(ErrorMessageLock);
308 MesPrint(
"Illegal wildcard power combination.");
309 MUNLOCK(ErrorMessageLock);
313 if ( ( t[-1] <= NumSymbols && t[-1] > -MAXPOWER )
314 && ( symbols[t[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
315 *m %= symbols[t[-1]].maxpower;
316 if ( *m < 0 ) *m += symbols[t[-1]].maxpower;
317 if ( ( symbols[t[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
318 if ( ( ( symbols[t[-1]].maxpower & 1 ) == 0 ) &&
319 ( *m >= symbols[t[-1]].maxpower/2 ) ) {
320 *m -= symbols[t[-1]].maxpower/2; ncoef = -ncoef;
324 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
325 MLOCK(ErrorMessageLock);
326 MesPrint(
"Power overflow during normalization");
327 MUNLOCK(ErrorMessageLock);
333 { *m = m[2]; m++; *m = m[2]; m++; i++; }
340 }
while ( *t < *m && --i > 0 );
343 { m--; m[2] = *m; m--; m[2] = *m; i++; }
355 if ( t[1] == FUNNYVEC ) {
359 else if ( t[1] < 0 ) {
360 if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
362 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
365 else { *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2; }
371 if ( t[2] == 0 ) t += 3;
372 else if ( ndot > 0 && t[0] == ppdot[-3]
373 && t[1] == ppdot[-2] ) {
376 if ( ppdot[-1] == 0 ) { ppdot -= 3; ndot--; }
379 *ppdot++ = *t++; *ppdot++ = *t++;
380 *ppdot++ = *t++; ndot++;
387 if ( WildFill(BHEAD termout,term,AT.dummysubexp) < 0 )
goto FromNorm;
389 t = termout; m = term;
392 case DOLLAREXPRESSION :
399 if ( AR.Eside != LHSIDE ) {
402 int nummodopt, ptype = -1;
403 if ( AS.MultiThreaded ) {
404 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
405 if ( t[2] == ModOptdollars[nummodopt].number )
break;
407 if ( nummodopt < NumModOptdollars ) {
408 ptype = ModOptdollars[nummodopt].type;
409 if ( ptype == MODLOCAL ) {
410 d = ModOptdollars[nummodopt].dstruct+AT.identity;
413 LOCK(d->pthreadslockread);
418 if ( d->type == DOLZERO ) {
420 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
422 if ( t[3] == 0 )
goto NormZZ;
423 if ( t[3] < 0 )
goto NormInf;
426 else if ( d->type == DOLNUMBER ) {
429 nnum = d->where[nnum-1];
430 if ( nnum < 0 ) { ncoef = -ncoef; nnum = -nnum; }
432 for ( i = 1; i <= nnum; i++ ) lnum[i-1] = d->where[i];
434 if ( nnum == 0 || ( nnum == 1 && lnum[0] == 0 ) ) {
436 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
438 if ( t[3] < 0 )
goto NormInf;
439 else if ( t[3] == 0 )
goto NormZZ;
442 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
443 ncoef = REDLENG(ncoef);
445 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
447 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
452 else if ( t[3] > 0 ) {
453 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) ) {
455 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
460 ncoef = INCLENG(ncoef);
462 else if ( d->type == DOLINDEX ) {
463 if ( d->index == 0 ) {
465 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
469 if ( d->index != NOINDEX ) pind[nind++] = d->index;
471 else if ( d->type == DOLTERMS ) {
472 t[0] = SUBEXPRESSION;
476 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
483 if ( *t == DOLLAREXPRESSION ) {
485 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
489 if ( AS.MultiThreaded ) {
490 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
491 if ( t[2] == ModOptdollars[nummodopt].number )
break;
493 if ( nummodopt < NumModOptdollars ) {
494 ptype = ModOptdollars[nummodopt].type;
495 if ( ptype == MODLOCAL ) {
496 d = ModOptdollars[nummodopt].dstruct+AT.identity;
499 LOCK(d->pthreadslockread);
504 if ( d->type == DOLTERMS ) {
505 t[0] = SUBEXPRESSION;
512 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
518 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
520 MLOCK(ErrorMessageLock);
521 MesPrint(
"!!!This $ variation has not been implemented yet!!!");
522 MUNLOCK(ErrorMessageLock);
526 if ( ptype > 0 && ptype != MODLOCAL ) { UNLOCK(d->pthreadslockread); }
542 if ( *t == SUMMEDIND ) {
543 if ( t[1] < -NMIN4SHIFT ) {
544 k = -t[1]-NMIN4SHIFT;
545 k = ExtraSymbol(k,1,nsym,ppsym,&ncoef);
549 else if ( t[1] == 0 )
goto NormZero;
559 ncoef = REDLENG(ncoef);
560 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
562 ncoef = INCLENG(ncoef);
566 else if ( *t == NOINDEX && t[1] == NOINDEX ) t += 2;
567 else if ( *t == EMPTYINDEX && t[1] == EMPTYINDEX ) {
568 *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2;
572 *ppdot++ = *t++; *ppdot++ = *t++; *ppdot++ = 1; ndot++;
575 *ppvec++ = *t++; *ppvec++ = *t++; nvec += 2;
580 *ppvec++ = t[1]; *ppvec++ = *t; t+=2; nvec += 2;
582 else { *ppdel++ = *t++; *ppdel++ = *t++; ndel += 2; }
590 if ( t[FUNHEAD] == -SNUMBER && t[1] == FUNHEAD+2
591 && t[FUNHEAD+1] >= 0 ) {
592 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
595 ncoef = REDLENG(ncoef);
596 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
597 ncoef = INCLENG(ncoef);
599 else pcom[ncom++] = t;
601 case BERNOULLIFUNCTION :
605 if ( ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 )
606 && ( t[1] == FUNHEAD+2 || ( t[1] == FUNHEAD+4 &&
607 t[FUNHEAD+2] == -SNUMBER && ABS(t[FUNHEAD+3]) == 1 ) ) ) {
609 if ( Bernoulli(t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
611 if ( nnum == 0 )
goto NormZero;
612 inum = nnum;
if ( inum < 0 ) inum = -inum;
615 while ( lnum[mnum-1] == 0 ) mnum--;
616 if ( nnum < 0 ) mnum = -mnum;
617 ncoef = REDLENG(ncoef);
618 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,mnum) )
goto FromNorm;
620 while ( lnum[inum+mnum-1] == 0 ) mnum--;
621 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)(lnum+inum),mnum) )
goto FromNorm;
622 ncoef = INCLENG(ncoef);
623 if ( t[1] == FUNHEAD+4 && t[FUNHEAD+1] == 1
624 && t[FUNHEAD+3] == -1 ) ncoef = -ncoef;
626 else pcom[ncom++] = t;
638 if ( k == 0 )
goto NormZero;
639 *((UWORD *)lnum) = k;
647 if ( *t == -EXPRESSION ) {
648 k = AS.OldNumFactors[t[1]];
650 else if ( *t == -DOLLAREXPRESSION ) {
651 k = Dollars[t[1]].nfactors;
657 if ( k == 0 )
goto NormZero;
658 *((UWORD *)lnum) = k;
665 if ( t[FUNHEAD] < 0 ) {
666 if ( t[FUNHEAD] <= -FUNCTION && t[1] == FUNHEAD+1 )
break;
667 if ( t[FUNHEAD] > -FUNCTION && t[1] == FUNHEAD+2 ) {
668 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] == 0 )
goto NormZero;
674 if ( t[FUNHEAD] > 0 && t[FUNHEAD] == t[1]-FUNHEAD ) {
676 t += FUNHEAD+ARGHEAD;
681 if ( k == 0 )
goto NormZero;
682 *((UWORD *)lnum) = k;
686 else pcom[ncom++] = t;
690 k = CountFun(AN.cTerm,t);
691 if ( k == 0 )
goto NormZero;
692 if ( k > 0 ) { *((UWORD *)lnum) = k; nnum = 1; }
693 else { *((UWORD *)lnum) = -k; nnum = -1; }
698 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+2] == -SNUMBER
699 && t[1] == FUNHEAD+4 && t[FUNHEAD+3] > 1 ) {
701 if ( t[FUNHEAD+1] == 0 )
goto NormZero;
702 if ( t[FUNHEAD+1] < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; sgn = -1; }
704 if ( MakeRational(t[FUNHEAD+1],t[FUNHEAD+3],x1,x1+1) ) {
705 static int warnflag = 1;
707 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
710 x1[0] = t[FUNHEAD+1]; x1[1] = 1;
712 if ( sgn < 0 ) { t[FUNHEAD+1] = -t[FUNHEAD+1]; x1[0] = -x1[0]; }
713 if ( x1[0] < 0 ) { sgn = -1; x1[0] = -x1[0]; }
715 ncoef = REDLENG(ncoef);
716 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)x1,sgn,
717 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
718 ncoef = INCLENG(ncoef);
721 WORD narg = 0, *tt, *ttstop, *arg1 = 0, *arg2 = 0;
724 ttstop = t + t[1]; tt = t+FUNHEAD;
725 while ( tt < ttstop ) {
727 if ( narg == 1 ) arg1 = tt;
731 if ( narg != 2 )
goto defaultcase;
732 if ( *arg2 == -SNUMBER && arg2[1] <= 1 )
goto defaultcase;
733 else if ( *arg2 > 0 && ttstop[-1] < 0 )
goto defaultcase;
734 x1 = NumberMalloc(
"Norm-MakeRational");
735 if ( *arg1 == -SNUMBER ) {
736 if ( arg1[1] == 0 ) {
737 NumberFree(x1,
"Norm-MakeRational");
740 if ( arg1[1] < 0 ) { x1[0] = -arg1[1]; nx1 = -1; }
741 else { x1[0] = arg1[1]; nx1 = 1; }
743 else if ( *arg1 > 0 ) {
745 nx1 = (ABS(arg2[-1])-1)/2;
746 tc = arg1+ARGHEAD+1+nx1;
748 NumberFree(x1,
"Norm-MakeRational");
751 for ( i = 1; i < nx1; i++ )
if ( tc[i] != 0 ) {
752 NumberFree(x1,
"Norm-MakeRational");
756 for ( i = 0; i < nx1; i++ ) x1[i] = tc[i];
757 if ( arg2[-1] < 0 ) nx1 = -nx1;
760 NumberFree(x1,
"Norm-MakeRational");
763 x2 = NumberMalloc(
"Norm-MakeRational");
764 if ( *arg2 == -SNUMBER ) {
765 if ( arg2[1] <= 1 ) {
766 NumberFree(x2,
"Norm-MakeRational");
767 NumberFree(x1,
"Norm-MakeRational");
770 else { x2[0] = arg2[1]; nx2 = 1; }
772 else if ( *arg2 > 0 ) {
774 nx2 = (ttstop[-1]-1)/2;
775 tc = arg2+ARGHEAD+1+nx2;
777 NumberFree(x2,
"Norm-MakeRational");
778 NumberFree(x1,
"Norm-MakeRational");
781 for ( i = 1; i < nx2; i++ )
if ( tc[i] != 0 ) {
782 NumberFree(x2,
"Norm-MakeRational");
783 NumberFree(x1,
"Norm-MakeRational");
787 for ( i = 0; i < nx2; i++ ) x2[i] = tc[i];
790 NumberFree(x2,
"Norm-MakeRational");
791 NumberFree(x1,
"Norm-MakeRational");
794 if ( BigLong(x1,ABS(nx1),x2,nx2) >= 0 ) {
795 UWORD *x3 = NumberMalloc(
"Norm-MakeRational");
796 UWORD *x4 = NumberMalloc(
"Norm-MakeRational");
798 DivLong(x1,nx1,x2,nx2,x3,&nx3,x4,&nx4);
799 for ( i = 0; i < ABS(nx4); i++ ) x1[i] = x4[i];
801 NumberFree(x4,
"Norm-MakeRational");
802 NumberFree(x3,
"Norm-MakeRational");
804 xx = (UWORD *)(TermMalloc(
"Norm-MakeRational"));
805 if ( MakeLongRational(BHEAD x1,nx1,x2,nx2,xx,&nxx) ) {
806 static int warnflag = 1;
808 MesPrint(
"%w Warning: fraction could not be reconstructed in MakeRational_");
811 ncoef = REDLENG(ncoef);
812 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,x1,nx1) )
816 ncoef = REDLENG(ncoef);
817 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,xx,nxx,
818 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
820 ncoef = INCLENG(ncoef);
821 TermFree(xx,
"Norm-MakeRational");
822 NumberFree(x2,
"Norm-MakeRational");
823 NumberFree(x1,
"Norm-MakeRational");
827 if ( t[1] == FUNHEAD && AN.cTerm ) {
828 ANsr = r; ANsm = m; ANsc = AN.cTerm;
832 ncoef = REDLENG(ncoef);
833 nnum = REDLENG(m[-1]);
835 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)m,nnum,
836 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
837 ncoef = INCLENG(ncoef);
842 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
843 if ( GetFirstBracket(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
844 if ( *termout == 0 )
goto NormZero;
845 if ( *termout > 4 ) {
847 while ( r < m ) *t++ = *r++;
849 r2 = termout + *termout; r2 -= ABS(r2[-1]);
850 while ( r < r1 ) *r2++ = *r++;
852 while ( r3 < r2 ) *t++ = *r3++; *term = t - term;
853 if ( AT.WorkPointer > term && AT.WorkPointer < t )
861 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
864 POSITION oldondisk = AS.OldOnFile[t[FUNHEAD+1]];
865 if ( e->replace == NEWLYDEFINEDEXPRESSION ) {
866 AS.OldOnFile[t[FUNHEAD+1]] = e->onfile;
868 if ( *t == FIRSTTERM ) {
869 if ( GetFirstTerm(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
871 else if ( *t == CONTENTTERM ) {
872 if ( GetContent(termout,t[FUNHEAD+1]) < 0 )
goto FromNorm;
874 AS.OldOnFile[t[FUNHEAD+1]] = oldondisk;
875 if ( *termout == 0 )
goto NormZero;
879 WORD *r1, *r2, *r3, *r4, *r5, nr1, *rterm;
880 r2 = termout + *termout; lnum = r2 - ABS(r2[-1]);
881 nnum = REDLENG(r2[-1]);
883 r1 = term + *term; r3 = r1 - ABS(r1[-1]);
884 nr1 = REDLENG(r1[-1]);
885 if ( Mully(BHEAD (UWORD *)lnum,&nnum,(UWORD *)r3,nr1) )
goto FromNorm;
886 nnum = INCLENG(nnum); nr1 = ABS(nnum); lnum[nr1-1] = nnum;
887 rterm = TermMalloc(
"FirstTerm/ContentTerm");
888 r4 = rterm+1; r5 = term+1;
while ( r5 < t ) *r4++ = *r5++;
889 r5 = termout+1;
while ( r5 < lnum ) *r4++ = *r5++;
890 r5 = r;
while ( r5 < r3 ) *r4++ = *r5++;
891 r5 = lnum; NCOPY(r4,r5,nr1);
893 nr1 = *rterm; r1 = term; r2 = rterm; NCOPY(r1,r2,nr1);
894 TermFree(rterm,
"FirstTerm/ContentTerm");
895 if ( AT.WorkPointer > term && AT.WorkPointer < r1 )
900 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
901 DOLLARS d = Dollars + t[FUNHEAD+1], newd = 0;
904 int nummodopt, dtype = -1;
905 if ( AS.MultiThreaded && ( AC.mparallelflag == PARALLELFLAG ) ) {
906 for ( nummodopt = 0; nummodopt < NumModOptdollars; nummodopt++ ) {
907 if ( t[FUNHEAD+1] == ModOptdollars[nummodopt].number )
break;
909 if ( nummodopt < NumModOptdollars ) {
910 dtype = ModOptdollars[nummodopt].type;
911 if ( dtype == MODLOCAL ) {
912 d = ModOptdollars[nummodopt].dstruct+AT.identity;
917 if ( d->where && ( d->type == DOLTERMS || d->type == DOLNUMBER ) ) {
921 if ( ( newd = DolToTerms(BHEAD t[FUNHEAD+1]) ) == 0 )
924 if ( newd->where[0] == 0 ) {
925 M_free(newd,
"Copy of dollar variable");
928 if ( *t == FIRSTTERM ) {
929 idol = newd->where[0];
930 for ( ido = 0; ido < idol; ido++ ) termout[ido] = newd->where[ido];
932 else if ( *t == CONTENTTERM ) {
936 for ( ido = 0; ido < idol; ido++ ) termout[ido] = tterm[ido];
939 if ( ContentMerge(BHEAD termout,tterm) < 0 )
goto FromNorm;
944 if ( newd->factors ) M_free(newd->factors,
"Dollar factors");
945 M_free(newd,
"Copy of dollar variable");
953 if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -EXPRESSION ) {
954 x = TermsInExpression(t[FUNHEAD+1]);
955 multermnum:
if ( x == 0 )
goto NormZero;
958 if ( x > (LONG)WORDMASK ) { lnum[0] = x & WORDMASK;
959 lnum[1] = x >> BITSINWORD; nnum = -2;
961 else { lnum[0] = x; nnum = -1; }
963 else if ( x > (LONG)WORDMASK ) {
964 lnum[0] = x & WORDMASK;
965 lnum[1] = x >> BITSINWORD;
968 else { lnum[0] = x; nnum = 1; }
969 ncoef = REDLENG(ncoef);
970 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
972 ncoef = INCLENG(ncoef);
974 else if ( ( t[1] == FUNHEAD+2 ) && t[FUNHEAD] == -DOLLAREXPRESSION ) {
975 x = TermsInDollar(t[FUNHEAD+1]);
978 else { pcom[ncom++] = t; }
982 case PATTERNFUNCTION:
989 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
990 && t[FUNHEAD+1] >= 0 && t[FUNHEAD+2] == -SNUMBER
991 && t[FUNHEAD+3] >= 0 && t[FUNHEAD+1] >= t[FUNHEAD+3] ) {
992 if ( t[FUNHEAD+1] > t[FUNHEAD+3] ) {
993 if ( GetBinom((UWORD *)lnum,&nnum,
994 t[FUNHEAD+1],t[FUNHEAD+3]) )
goto FromNorm;
995 if ( nnum == 0 )
goto NormZero;
999 else pcom[ncom++] = t;
1005 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1006 if ( ( t[FUNHEAD+1] & 1 ) != 0 ) ncoef = -ncoef;
1008 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1009 && ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) ) {
1010 UWORD *numer1,*denom1;
1011 WORD nsize = abs(t[t[1]-1]), nnsize, isize;
1012 nnsize = (nsize-1)/2;
1013 numer1 = (UWORD *)(t + FUNHEAD+ARGHEAD+1);
1014 denom1 = numer1 + nnsize;
1015 for ( isize = 1; isize < nnsize; isize++ ) {
1016 if ( denom1[isize] )
break;
1018 if ( ( denom1[0] != 1 ) || isize < nnsize ) {
1022 if ( ( numer1[0] & 1 ) != 0 ) ncoef = -ncoef;
1036 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1037 if ( t[FUNHEAD+1] < 0 ) ncoef = -ncoef;
1039 else if ( ( t[1] == FUNHEAD+2 ) && ( t[FUNHEAD] == -SYMBOL )
1040 && ( ( t[FUNHEAD+1] <= NumSymbols && t[FUNHEAD+1] > -MAXPOWER )
1041 && ( symbols[t[FUNHEAD+1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) ) {
1051 *m %= symbols[k].maxpower;
1052 if ( ( symbols[k].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1053 if ( ( ( symbols[k].maxpower & 1 ) == 0 ) &&
1054 ( *m >= symbols[k].maxpower/2 ) ) {
1055 *m -= symbols[k].maxpower/2; ncoef = -ncoef;
1061 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1067 }
while ( k < *m && --i > 0 );
1070 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1078 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] ) ) {
1079 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1080 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1085 else if ( ( t[FUNHEAD+ARGHEAD]+FUNHEAD+ARGHEAD == t[1] )
1086 && ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) ) {
1087 WORD *ts = t + FUNHEAD+ARGHEAD+3;
1088 WORD its = ts[-1]-2;
1090 if ( ( *ts != 0 ) && ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1091 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY ) ) {
1100 if ( t[t[1]-1] < 0 ) ncoef = -ncoef;
1101 ts = t + FUNHEAD+ARGHEAD+3;
1112 if ( ( ts[-1] <= NumSymbols && ts[-1] > -MAXPOWER ) &&
1113 ( symbols[ts[-1]].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
1114 *m %= symbols[ts[-1]].maxpower;
1115 if ( *m < 0 ) *m += symbols[ts[-1]].maxpower;
1116 if ( ( symbols[ts[-1]].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
1117 if ( ( ( symbols[ts[-1]].maxpower & 1 ) == 0 ) &&
1118 ( *m >= symbols[ts[-1]].maxpower/2 ) ) {
1119 *m -= symbols[ts[-1]].maxpower/2; ncoef = -ncoef;
1126 { *m = m[2]; m++; *m = m[2]; m++; i++; }
1133 }
while ( *ts < *m && --i > 0 );
1136 { m--; m[2] = *m; m--; m[2] = *m; i++; }
1146 signogood: pcom[ncom++] = t;
1149 else pcom[ncom++] = t;
1156 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1158 if ( k < 0 ) k = -k;
1159 if ( k == 0 )
goto NormZero;
1160 *((UWORD *)lnum) = k; nnum = 1;
1164 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SYMBOL ) {
1166 if ( ( k > NumSymbols || k <= -MAXPOWER )
1167 || ( symbols[k].complex & VARTYPEROOTOFUNITY ) != VARTYPEROOTOFUNITY )
1170 else if ( ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+t[FUNHEAD] )
1171 && ( t[1] == FUNHEAD+ARGHEAD+t[FUNHEAD+ARGHEAD] ) ) {
1172 if ( t[FUNHEAD] == ARGHEAD+1+abs(t[t[1]-1]) ) {
1174 absnosymbols: ts = t + t[1] -1;
1175 ncoef = REDLENG(ncoef);
1176 nnum = REDLENG(*ts);
1177 if ( nnum < 0 ) nnum = -nnum;
1178 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,
1179 (UWORD *)(ts-ABS(*ts)+1),nnum,
1180 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
1181 ncoef = INCLENG(ncoef);
1186 else if ( t[FUNHEAD+ARGHEAD+1] == SYMBOL ) {
1187 WORD *ts = t+FUNHEAD+ARGHEAD+1;
1188 WORD its = ts[1] - 2;
1192 else if ( ( *ts > NumSymbols || *ts <= -MAXPOWER )
1193 || ( symbols[*ts].complex & VARTYPEROOTOFUNITY )
1194 != VARTYPEROOTOFUNITY )
goto absnogood;
1200 absnogood: pcom[ncom++] = t;
1203 else pcom[ncom++] = t;
1211 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1212 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+3] > 1 ) {
1214 tmod = (t[FUNHEAD+1]%t[FUNHEAD+3]);
1215 if ( tmod < 0 ) tmod += t[FUNHEAD+3];
1216 if ( *t == MOD2FUNCTION && tmod > t[FUNHEAD+3]/2 )
1217 tmod -= t[FUNHEAD+3];
1219 *((UWORD *)lnum) = -tmod;
1222 else if ( tmod > 0 ) {
1223 *((UWORD *)lnum) = tmod;
1229 else if ( t[1] > t[FUNHEAD+2] && t[FUNHEAD] > 0
1230 && t[FUNHEAD+t[FUNHEAD]] == -SNUMBER
1231 && t[FUNHEAD+t[FUNHEAD]+1] > 1
1232 && t[1] == FUNHEAD+2+t[FUNHEAD] ) {
1233 WORD *ttt = t+FUNHEAD, iii;
1235 if ( *ttt == ttt[ARGHEAD]+ARGHEAD &&
1236 ttt[ARGHEAD] == ABS(iii)+1 ) {
1238 WORD cmod = ttt[*ttt+1];
1240 if ( *t == MODFUNCTION ) {
1241 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1242 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|NOINVERSES) )
1246 if ( TakeModulus((UWORD *)(ttt+ARGHEAD+1)
1247 ,&iii,(UWORD *)(&cmod),ncmod,UNPACK|POSNEG|NOINVERSES) )
1250 if ( *t == MOD2FUNCTION && ttt[ARGHEAD+1] > cmod/2 && iii > 0 ) {
1251 ttt[ARGHEAD+1] -= cmod;
1253 if ( ttt[ARGHEAD+1] < 0 ) {
1254 *((UWORD *)lnum) = -ttt[ARGHEAD+1];
1257 else if ( ttt[ARGHEAD+1] > 0 ) {
1258 *((UWORD *)lnum) = ttt[ARGHEAD+1];
1265 else if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER ) {
1266 *((UWORD *)lnum) = t[FUNHEAD+1];
1267 if ( *lnum == 0 )
goto NormZero;
1271 else if ( ( ( t[FUNHEAD] < 0 ) && ( t[FUNHEAD] == -SNUMBER )
1272 && ( t[1] >= ( FUNHEAD+6+ARGHEAD ) )
1273 && ( t[FUNHEAD+2] >= 4+ARGHEAD )
1274 && ( t[t[1]-1] == t[FUNHEAD+2+ARGHEAD]-1 ) ) ||
1275 ( ( t[FUNHEAD] > 0 )
1276 && ( t[FUNHEAD]-ARGHEAD-1 == ABS(t[FUNHEAD+t[FUNHEAD]-1]) )
1277 && ( t[FUNHEAD+t[FUNHEAD]]-ARGHEAD-1 == t[t[1]-1] ) ) ) {
1281 WORD *ttt = t + t[1], iii, iii1;
1282 UWORD coefbuf[2], *coef2, ncoef2;
1283 iii = (ttt[-1]-1)/2;
1285 if ( ttt[-1] != 1 ) {
1291 for ( iii1 = 0; iii1 < iii; iii1++ ) {
1292 if ( ttt[iii1] != 0 )
goto exitfromhere;
1303 nnum = -1; lnum[0] = -ttt[1]; lnum[1] = 1;
1306 nnum = 1; lnum[0] = ttt[1]; lnum[1] = 1;
1310 nnum = ABS(ttt[ttt[0]-1] - 1);
1311 for ( iii = 0; iii < nnum; iii++ ) {
1312 lnum[iii] = ttt[ARGHEAD+1+iii];
1315 if ( ttt[ttt[0]-1] < 0 ) nnum = -nnum;
1320 ncoef2 = 3; *coef2 = (UWORD)(ttt[1]);
1324 coef2 = (UWORD *)(ttt+ARGHEAD+1);
1325 ncoef2 = (ttt[ttt[0]-1]-1)/2;
1327 if ( TakeModulus((UWORD *)lnum,&nnum,(UWORD *)coef2,ncoef2,
1328 UNPACK|NOINVERSES|FROMFUNCTION) ) {
1331 if ( *t == MOD2FUNCTION && nnum > 0 ) {
1332 UWORD *coef3 = NumberMalloc(
"Mod2Function"), two = 2;
1334 if ( MulLong((UWORD *)lnum,nnum,&two,1,coef3,&ncoef3) )
1336 if ( BigLong(coef3,ncoef3,(UWORD *)coef2,ncoef2) > 0 ) {
1338 AddLong((UWORD *)lnum,nnum,(UWORD *)coef2,ncoef2
1339 ,(UWORD *)lnum,&nnum);
1342 NumberFree(coef3,
"Mod2Function");
1347 ncoef = REDLENG(ncoef);
1348 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
1350 ncoef = INCLENG(ncoef);
1352 else pcom[ncom++] = t;
1356 WORD argcount = 0, *tc, *ts, xc, xs, *tcc;
1357 UWORD *Num1, *Num2, *Num3, *Num4;
1358 WORD size1, size2, size3, size4, space;
1359 tc = t+FUNHEAD; ts = t + t[1];
1360 while ( argcount < 3 && tc < ts ) { NEXTARG(tc); argcount++; }
1361 if ( argcount != 2 )
goto defaultcase;
1362 if ( t[FUNHEAD] == -SNUMBER ) {
1363 if ( t[FUNHEAD+1] <= 1 )
goto defaultcase;
1364 if ( t[FUNHEAD+2] == -SNUMBER ) {
1365 if ( t[FUNHEAD+3] <= 1 )
goto defaultcase;
1366 Num2 = NumberMalloc(
"modinverses");
1367 *Num2 = t[FUNHEAD+3]; size2 = 1;
1370 if ( ts[-1] < 0 )
goto defaultcase;
1371 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1374 if ( *tcc != 1 )
goto defaultcase;
1375 for ( i = 1; i < xs; i++ ) {
1376 if ( tcc[i] != 0 )
goto defaultcase;
1378 Num2 = NumberMalloc(
"modinverses");
1380 for ( i = 0; i < xs; i++ ) Num2[i] = t[FUNHEAD+ARGHEAD+3+i];
1382 Num1 = NumberMalloc(
"modinverses");
1383 *Num1 = t[FUNHEAD+1]; size1 = 1;
1386 tc = t + FUNHEAD + t[FUNHEAD];
1387 if ( tc[-1] < 0 )
goto defaultcase;
1388 if ( tc[-1] != t[FUNHEAD]-ARGHEAD-1 )
goto defaultcase;
1391 if ( *tcc != 1 )
goto defaultcase;
1392 for ( i = 1; i < xc; i++ ) {
1393 if ( tcc[i] != 0 )
goto defaultcase;
1395 if ( *tc == -SNUMBER ) {
1396 if ( tc[1] <= 1 )
goto defaultcase;
1397 Num2 = NumberMalloc(
"modinverses");
1398 *Num2 = tc[1]; size2 = 1;
1401 if ( ts[-1] < 0 )
goto defaultcase;
1402 if ( ts[-1] != t[FUNHEAD+2]-ARGHEAD-1 )
goto defaultcase;
1405 if ( *tcc != 1 )
goto defaultcase;
1406 for ( i = 1; i < xs; i++ ) {
1407 if ( tcc[i] != 0 )
goto defaultcase;
1409 Num2 = NumberMalloc(
"modinverses");
1411 for ( i = 0; i < xs; i++ ) Num2[i] = tc[ARGHEAD+1+i];
1413 Num1 = NumberMalloc(
"modinverses");
1415 for ( i = 0; i < xc; i++ ) Num1[i] = t[FUNHEAD+ARGHEAD+1+i];
1417 Num3 = NumberMalloc(
"modinverses");
1418 Num4 = NumberMalloc(
"modinverses");
1419 GetLongModInverses(BHEAD Num1,size1,Num2,size2
1420 ,Num3,&size3,Num4,&size4);
1429 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) space += 2;
1430 else space += ARGHEAD + 2*ABS(size3) + 2;
1431 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) space += 2;
1432 else space += ARGHEAD + 2*ABS(size4) + 2;
1433 tt = term + *term; u = tt + space;
1434 while ( tt >= ts ) *--u = *--tt;
1435 m += space; r += space;
1438 if ( ( size3 == 1 || size3 == -1 ) && (*Num3&TOPBITONLY) == 0 ) {
1439 *ts++ = -SNUMBER; *ts = (WORD)(*Num3);
1440 if ( size3 < 0 ) *ts = -*ts;
1444 *ts++ = 2*ABS(size3)+ARGHEAD+2;
1445 *ts++ = 0; FILLARG(ts)
1446 *ts++ = 2*ABS(size3)+1;
1447 for ( i = 0; i < ABS(size3); i++ ) *ts++ = Num3[i];
1449 for ( i = 1; i < ABS(size3); i++ ) *ts++ = 0;
1450 if ( size3 < 0 ) *ts++ = 2*size3-1;
1451 else *ts++ = 2*size3+1;
1453 if ( ( size4 == 1 || size4 == -1 ) && (*Num4&TOPBITONLY) == 0 ) {
1454 *ts++ = -SNUMBER; *ts = *Num4;
1455 if ( size4 < 0 ) *ts = -*ts;
1459 *ts++ = 2*ABS(size4)+ARGHEAD+2;
1460 *ts++ = 0; FILLARG(ts)
1461 *ts++ = 2*ABS(size4)+2;
1462 for ( i = 0; i < ABS(size4); i++ ) *ts++ = Num4[i];
1464 for ( i = 1; i < ABS(size4); i++ ) *ts++ = 0;
1465 if ( size4 < 0 ) *ts++ = 2*size4-1;
1466 else *ts++ = 2*size4+1;
1468 NumberFree(Num4,
"modinverses");
1469 NumberFree(Num3,
"modinverses");
1470 NumberFree(Num1,
"modinverses");
1471 NumberFree(Num2,
"modinverses");
1478 #ifdef NEWGCDFUNCTION 1484 WORD *num1, *num2, size1, size2, stor1, stor2, *ttt, ti;
1485 if ( t[1] == FUNHEAD+4 && t[FUNHEAD] == -SNUMBER
1486 && t[FUNHEAD+2] == -SNUMBER && t[FUNHEAD+1] != 0
1487 && t[FUNHEAD+3] != 0 ) {
1488 stor1 = t[FUNHEAD+1];
1489 stor2 = t[FUNHEAD+3];
1490 if ( stor1 < 0 ) stor1 = -stor1;
1491 if ( stor2 < 0 ) stor2 = -stor2;
1492 num1 = &stor1; num2 = &stor2;
1496 else if ( t[1] > FUNHEAD+4 ) {
1497 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] != 0
1498 && t[FUNHEAD+2] == t[1]-FUNHEAD-2 &&
1499 ABS(t[t[1]-1]) == t[FUNHEAD+2]-1-ARGHEAD ) {
1501 size2 = ABS(num2[-1]);
1504 size2 = (size2-1)/2;
1506 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1507 if ( ti == 1 && ttt[-1] == 1 ) {
1508 stor1 = t[FUNHEAD+1];
1509 if ( stor1 < 0 ) stor1 = -stor1;
1514 else pcom[ncom++] = t;
1516 else if ( t[FUNHEAD] > 0 &&
1517 t[FUNHEAD]-1-ARGHEAD == ABS(t[t[FUNHEAD]+FUNHEAD-1]) ) {
1518 num1 = t + FUNHEAD + t[FUNHEAD];
1519 size1 = ABS(num1[-1]);
1522 size1 = (size1-1)/2;
1524 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1525 if ( ti == 1 && ttt[-1] == 1 ) {
1526 if ( t[1]-FUNHEAD == t[FUNHEAD]+2 && t[t[1]-2] == -SNUMBER
1527 && t[t[1]-1] != 0 ) {
1529 if ( stor2 < 0 ) stor2 = -stor2;
1534 else if ( t[1]-FUNHEAD == t[FUNHEAD]+t[FUNHEAD+t[FUNHEAD]]
1535 && ABS(t[t[1]-1]) == t[FUNHEAD+t[FUNHEAD]] - ARGHEAD-1 ) {
1537 size2 = ABS(num2[-1]);
1540 size2 = (size2-1)/2;
1542 while ( ti > 1 && ttt[-1] == 0 ) { ttt--; ti--; }
1543 if ( ti == 1 && ttt[-1] == 1 ) {
1544 gcdcalc:
if ( GcdLong(BHEAD (UWORD *)num1,size1,(UWORD *)num2,size2
1545 ,(UWORD *)lnum,&nnum) )
goto FromNorm;
1548 else pcom[ncom++] = t;
1550 else pcom[ncom++] = t;
1552 else pcom[ncom++] = t;
1554 else pcom[ncom++] = t;
1556 else pcom[ncom++] = t;
1560 WORD *gcd = AT.WorkPointer;
1561 if ( ( gcd = EvaluateGcd(BHEAD t) ) == 0 )
goto FromNorm;
1562 if ( *gcd == 4 && gcd[1] == 1 && gcd[2] == 1 && gcd[4] == 0 ) {
1563 AT.WorkPointer = gcd;
1565 else if ( gcd[*gcd] == 0 ) {
1566 WORD *t1, iii, change, *num, *den, numsize, densize;
1567 if ( gcd[*gcd-1] < *gcd-1 ) {
1569 for ( iii = 2; iii < t1[1]; iii += 2 ) {
1570 change = ExtraSymbol(t1[iii],t1[iii+1],nsym,ppsym,&ncoef);
1572 ppsym += change << 1;
1576 iii = t1[-1]; num = t1-iii; numsize = (iii-1)/2;
1577 den = num + numsize; densize = numsize;
1578 while ( numsize > 1 && num[numsize-1] == 0 ) numsize--;
1579 while ( densize > 1 && den[densize-1] == 0 ) densize--;
1580 if ( numsize > 1 || num[0] != 1 ) {
1581 ncoef = REDLENG(ncoef);
1582 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)num,numsize) )
goto FromNorm;
1583 ncoef = INCLENG(ncoef);
1585 if ( densize > 1 || den[0] != 1 ) {
1586 ncoef = REDLENG(ncoef);
1587 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)den,densize) )
goto FromNorm;
1588 ncoef = INCLENG(ncoef);
1590 AT.WorkPointer = gcd;
1604 LONG size = AT.WorkPointer - gcd;
1606 ss = AddRHS(AT.ebufnum,1);
1607 while ( (ss + size + 10) > C->
Top ) ss = DoubleCbuffer(AT.ebufnum,ss);
1610 C->
rhs[C->numrhs+1] = ss;
1613 t[0] = SUBEXPRESSION;
1620 while ( r < tt ) *t++ = *r++;
1629 MesPrint(
" Unexpected call to EvaluateGCD");
1635 if ( t[1] == FUNHEAD )
break;
1637 WORD *ttt = t + FUNHEAD;
1638 WORD *tttstop = t + t[1];
1640 while ( ttt < tttstop ) {
1642 if ( ttt[ARGHEAD]-1 > ABS(ttt[*ttt-1]) )
goto nospec;
1646 if ( *ttt != -SNUMBER )
goto nospec;
1657 for ( iii = 0; iii < ttt[ARGHEAD]; iii++ )
1658 AT.n_llnum[iii] = ttt[ARGHEAD+iii];
1663 if ( ttt[1] == 0 ) {
1664 AT.n_llnum[0] = AT.n_llnum[1] = AT.n_llnum[2] = AT.n_llnum[3] = 0;
1668 if ( ttt[1] > 0 ) { AT.n_llnum[1] = ttt[1]; AT.n_llnum[3] = 3; }
1669 else { AT.n_llnum[1] = -ttt[1]; AT.n_llnum[3] = -3; }
1677 while ( ttt < tttstop ) {
1679 if ( AT.n_llnum[0] == 0 ) {
1680 if ( ( *t == MINFUNCTION && ttt[*ttt-1] < 0 )
1681 || ( *t == MAXFUNCTION && ttt[*ttt-1] > 0 ) )
1687 if ( ( iii > 0 && *t == MINFUNCTION )
1688 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1689 for ( iii = 0; iii < ttt[0]; iii++ )
1690 AT.n_llnum[iii] = ttt[iii];
1696 if ( AT.n_llnum[0] == 0 ) {
1697 if ( ( *t == MINFUNCTION && ttt[1] < 0 )
1698 || ( *t == MAXFUNCTION && ttt[1] > 0 ) )
1701 else if ( ttt[1] == 0 ) {
1702 if ( ( *t == MINFUNCTION && AT.n_llnum[*AT.n_llnum-1] > 0 )
1703 || ( *t == MAXFUNCTION && AT.n_llnum[*AT.n_llnum-1] < 0 ) ) {
1708 tterm[0] = 4; tterm[2] = 1;
1709 if ( ttt[1] < 0 ) { tterm[1] = -ttt[1]; tterm[3] = -3; }
1710 else { tterm[1] = ttt[1]; tterm[3] = 3; }
1712 if ( ( iii > 0 && *t == MINFUNCTION )
1713 || ( iii < 0 && *t == MAXFUNCTION ) ) {
1714 for ( iii = 0; iii < 4; iii++ )
1715 AT.n_llnum[iii] = tterm[iii];
1721 if ( AT.n_llnum[0] == 0 )
goto NormZero;
1722 ncoef = REDLENG(ncoef);
1723 nnum = REDLENG(AT.n_llnum[*AT.n_llnum-1]);
1724 if ( MulRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)lnum,nnum,
1725 (UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
1726 ncoef = INCLENG(ncoef);
1729 case INVERSEFACTORIAL:
1730 if ( t[FUNHEAD] == -SNUMBER && t[FUNHEAD+1] >= 0 ) {
1731 if ( Factorial(BHEAD t[FUNHEAD+1],(UWORD *)lnum,&nnum) )
1733 ncoef = REDLENG(ncoef);
1734 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
goto FromNorm;
1735 ncoef = INCLENG(ncoef);
1738 nospec: pcom[ncom++] = t;
1742 if ( ( t[FUNHEAD] == -SYMBOL )
1743 && ( t[FUNHEAD+1] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1744 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].maxpower;
1748 else { pcom[ncom++] = t; }
1751 if ( ( t[FUNHEAD] == -SYMBOL )
1752 && ( t[FUNHEAD] > 0 ) && ( t[1] == FUNHEAD+2 ) ) {
1753 *((UWORD *)lnum) = symbols[t[FUNHEAD+1]].minpower;
1757 else { pcom[ncom++] = t; }
1760 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER
1761 && t[FUNHEAD+1] > 0 ) {
1762 UWORD xp = (UWORD)(
NextPrime(BHEAD t[FUNHEAD+1]));
1763 ncoef = REDLENG(ncoef);
1764 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,&xp,1) )
goto FromNorm;
1765 ncoef = INCLENG(ncoef);
1767 else goto defaultcase;
1770 ncoef = REDLENG(ncoef);
1771 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)(t+3),t[2]) )
goto FromNorm;
1772 ncoef = INCLENG(ncoef);
1777 if ( t[3] & 1 ) ncoef = -ncoef;
1779 else if ( t[2] == 0 ) {
1780 if ( t[3] < 0 )
goto NormInf;
1785 if ( t[3] && RaisPow(BHEAD (UWORD *)lnum,&nnum,(UWORD)(ABS(t[3]))) )
goto FromNorm;
1786 ncoef = REDLENG(ncoef);
1788 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
1791 else if ( t[3] > 0 ) {
1792 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
1795 ncoef = INCLENG(ncoef);
1807 if ( ( t[2] & DIRTYFLAG ) == DIRTYFLAG ) {
1809 t[2] |= DIRTYSYMFLAG;
1812 ScanCont:
while ( t < r ) {
1813 if ( *t >= AM.OffsetIndex &&
1814 ( *t >= AM.DumInd || ( *t < AM.WilInd &&
1815 indices[*t-AM.OffsetIndex].dimension ) ) )
1825 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) )
1827 if ( *rr == -SNUMBER && rr[1] == 1 )
break;
1828 if ( *rr <= -FUNCTION ) k = *rr;
1830 if ( *rr == ARGHEAD || ( *rr == -SNUMBER && rr[1] == 0 ) ) {
1831 if ( k == 0 )
goto NormZZ;
1834 if ( *rr == -SNUMBER && rr[1] > 0 && rr[1] < MAXPOWER && k < 0 ) {
1836 if ( functions[k-FUNCTION].commute ) {
1837 for ( i = 0; i < rr[1]; i++ ) pnco[nnco++] = rr-1;
1840 for ( i = 0; i < rr[1]; i++ ) pcom[ncom++] = rr-1;
1844 if ( k == 0 )
goto NormZero;
1845 if ( t[FUNHEAD] == -SYMBOL && *rr == -SNUMBER && t[1] == FUNHEAD+4 ) {
1846 if ( rr[1] < MAXPOWER ) {
1847 t = rr; *rr = t[FUNHEAD+1];
1856 t[2] &= ~DIRTYSYMFLAG;
1862 t[2] &= ~DIRTYSYMFLAG;
1869 if ( *t == 0 )
goto NormZero;
1870 if ( *t > 0 && *t < AM.OffsetIndex ) {
1873 ncoef = REDLENG(ncoef);
1874 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)lnum,nnum) )
1876 ncoef = INCLENG(ncoef);
1878 else if ( *t == NOINDEX ) t++;
1879 else pind[nind++] = *t++;
1882 case SUBEXPRESSION :
1883 if ( t[3] == 0 )
break;
1895 if ( t[2] == 0 )
goto defaultcase;
1896 if ( t[FUNHEAD] != -SNUMBER || t[FUNHEAD+1] < 0 )
goto defaultcase;
1897 if ( t[FUNHEAD+2] == -SNUMBER ) {
1898 if ( t[FUNHEAD+1] == 0 && t[FUNHEAD+3] == 0 )
goto NormZZ;
1899 if ( t[FUNHEAD+1] == 0 )
break;
1900 if ( t[FUNHEAD+3] < 0 ) {
1901 AT.WorkPointer[0] = -t[FUNHEAD+3];
1905 AT.WorkPointer[0] = t[FUNHEAD+3];
1908 AT.WorkPointer[1] = 1;
1910 else if ( t[FUNHEAD+2] == t[1]-FUNHEAD-2
1911 && t[FUNHEAD+2] == t[FUNHEAD+2+ARGHEAD]+ARGHEAD
1912 && ABS(t[t[1]-1]) == t[FUNHEAD+2+ARGHEAD] - 1 ) {
1914 if ( t[FUNHEAD+1] == 0 )
break;
1915 i = t[t[1]-1]; r1 = t + FUNHEAD+ARGHEAD+3;
1918 r2 = AT.WorkPointer;
1919 while ( --i >= 0 ) *r2++ = *r1++;
1921 else goto defaultcase;
1922 if ( TakeRatRoot((UWORD *)AT.WorkPointer,&nc,t[FUNHEAD+1]) ) {
1926 ncoef = REDLENG(ncoef);
1927 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)AT.WorkPointer,nc) )
1929 if ( nc < 0 ) nc = -nc;
1930 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)(AT.WorkPointer+nc),nc) )
1932 ncoef = INCLENG(ncoef);
1935 case RANDOMFUNCTION :
1937 WORD nnc, nc, nca, nr;
1948 if ( t[1] == FUNHEAD )
goto defaultcase;
1949 if ( t[1] == FUNHEAD+2 && t[FUNHEAD] == -SNUMBER &&
1950 t[FUNHEAD+1] > 0 ) {
1951 if ( t[FUNHEAD+1] == 1 )
break;
1953 ((UWORD *)AT.WorkPointer)[0] = wranf(BHEAD0);
1954 ((UWORD *)AT.WorkPointer)[1] = wranf(BHEAD0);
1956 if ( ((UWORD *)AT.WorkPointer)[1] == 0 ) {
1958 if ( ((UWORD *)AT.WorkPointer)[0] == 0 ) {
1962 xx = (UWORD)(t[FUNHEAD+1]);
1964 DivLong((UWORD *)AT.WorkPointer,nr
1966 ,((UWORD *)AT.WorkPointer)+4,&nnc
1967 ,((UWORD *)AT.WorkPointer)+2,&nc);
1968 ((UWORD *)AT.WorkPointer)[4] = 0;
1969 ((UWORD *)AT.WorkPointer)[5] = 0;
1970 ((UWORD *)AT.WorkPointer)[6] = 1;
1971 DivLong((UWORD *)AT.WorkPointer+4,3
1973 ,((UWORD *)AT.WorkPointer)+9,&nnc
1974 ,((UWORD *)AT.WorkPointer)+7,&nca);
1975 AddLong((UWORD *)AT.WorkPointer+4,3
1976 ,((UWORD *)AT.WorkPointer)+7,-nca
1977 ,((UWORD *)AT.WorkPointer)+9,&nnc);
1978 if ( BigLong((UWORD *)AT.WorkPointer,nr
1979 ,((UWORD *)AT.WorkPointer)+9,nnc) >= 0 )
goto redoshort;
1983 AT.WorkPointer[2] = (WORD)xx;
1986 ncoef = REDLENG(ncoef);
1987 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+2,nc) )
1989 ncoef = INCLENG(ncoef);
1991 else if ( t[FUNHEAD] > 0 && t[1] == t[FUNHEAD]+FUNHEAD
1992 && ABS(t[t[1]-1]) == t[FUNHEAD]-1-ARGHEAD && t[t[1]-1] > 0 ) {
1993 WORD nna, nnb, nni, nnb2, nnb2a;
1998 nnt = (UWORD *)(t+t[1]-1-nnb);
1999 if ( *nnt != 1 )
goto defaultcase;
2000 for ( nni = 1; nni < nnb; nni++ ) {
2001 if ( nnt[nni] != 0 )
goto defaultcase;
2003 nnt = (UWORD *)(t + FUNHEAD + ARGHEAD + 1);
2005 for ( nni = 0; nni < nnb2; nni++ ) {
2006 ((UWORD *)AT.WorkPointer)[nni] = wranf(BHEAD0);
2009 while ( nnb2a > 0 && ((UWORD *)AT.WorkPointer)[nnb2a-1] == 0 ) nnb2a--;
2011 DivLong((UWORD *)AT.WorkPointer,nnb2a
2013 ,((UWORD *)AT.WorkPointer)+2*nnb2,&nnc
2014 ,((UWORD *)AT.WorkPointer)+nnb2,&nc);
2015 for ( nni = 0; nni < nnb2; nni++ ) {
2016 ((UWORD *)AT.WorkPointer)[nni+2*nnb2] = 0;
2018 ((UWORD *)AT.WorkPointer)[3*nnb2] = 1;
2019 DivLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2021 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc
2022 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,&nca);
2023 AddLong((UWORD *)AT.WorkPointer+2*nnb2,nnb2+1
2024 ,((UWORD *)AT.WorkPointer)+3*nnb2+1,-nca
2025 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,&nnc);
2026 if ( BigLong((UWORD *)AT.WorkPointer,nnb2a
2027 ,((UWORD *)AT.WorkPointer)+4*nnb2+1,nnc) >= 0 )
goto redoshort;
2031 for ( nni = 0; nni < nnb; nni++ ) {
2032 ((UWORD *)AT.WorkPointer)[nnb2+nni] = nnt[nni];
2036 ncoef = REDLENG(ncoef);
2037 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,((UWORD *)(AT.WorkPointer))+nnb2,nc) )
2039 ncoef = INCLENG(ncoef);
2041 else goto defaultcase;
2045 if ( *t == RANPERM && t[1] > FUNHEAD && t[FUNHEAD] <= -FUNCTION ) {
2047 WORD *mm, *ww, *ow = AT.WorkPointer;
2048 WORD *Array, *targ, *argstop, narg = 0, itot;
2052 while ( targ < argstop ) {
2053 narg++; NEXTARG(targ);
2055 WantAddPointers(narg);
2056 pwork = AT.pWorkSpace + AT.pWorkPointer;
2057 targ = t+FUNHEAD+1; narg = 0;
2058 while ( targ < argstop ) {
2059 pwork[narg++] = targ;
2066 ow = AT.WorkPointer;
2067 Array = AT.WorkPointer;
2068 AT.WorkPointer += narg;
2069 for ( i = 0; i < narg; i++ ) Array[i] = i;
2070 for ( i = 2; i <= narg; i++ ) {
2071 itot = (WORD)(iranf(BHEAD i));
2072 for ( j = 0; j < itot; j++ ) CYCLE1(WORD,Array,i)
2074 mm = AT.WorkPointer;
2075 *mm++ = -t[FUNHEAD];
2077 for ( ie = 2; ie < FUNHEAD; ie++ ) *mm++ = t[ie];
2078 for ( i = 0; i < narg; i++ ) {
2079 ww = pwork[Array[i]];
2082 mm = AT.WorkPointer; t++; ww = t;
2083 i = mm[1]; NCOPY(ww,mm,i)
2084 AT.WorkPointer = ow;
2098 if ( t[1] <= FUNHEAD ) break;
2103 if ( *to == ARGHEAD )
goto NormZero;
2107 if ( to[ARGHEAD] != j+1 )
goto NoInteg;
2108 if ( rr >= r ) k = -1;
2109 else if ( *rr == ARGHEAD ) { k = 0; rr += ARGHEAD; }
2110 else if ( *rr == -SNUMBER ) { k = rr[1]; rr += 2; }
2112 if ( rr != r )
goto NoInteg;
2113 if ( k > 1 || k < -1 )
goto NoInteg;
2116 i = ( i < 0 ) ? -j: j;
2117 UnPack((UWORD *)to,i,&den,&num);
2125 if ( AN.NoScrat2 == 0 ) {
2126 AN.NoScrat2 = (UWORD *)Malloc1((AM.MaxTal+2)*
sizeof(UWORD),
"Normalize");
2128 if ( DivLong((UWORD *)to,num,(UWORD *)(to+j),den
2129 ,(UWORD *)AT.WorkPointer,&num,AN.NoScrat2,&den) )
goto FromNorm;
2130 if ( k < 0 && den < 0 ) {
2133 if ( AddLong((UWORD *)AT.WorkPointer,num
2134 ,AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2137 else if ( k > 0 && den > 0 ) {
2140 if ( AddLong((UWORD *)AT.WorkPointer,num,
2141 AN.NoScrat2,den,(UWORD *)AT.WorkPointer,&num) )
2146 else if ( *to == -SNUMBER ) {
2147 if ( to[1] < 0 ) { *AT.WorkPointer = -to[1]; num = -1; }
2148 else if ( to[1] == 0 )
goto NormZero;
2149 else { *AT.WorkPointer = to[1]; num = 1; }
2152 if ( num == 0 )
goto NormZero;
2153 ncoef = REDLENG(ncoef);
2154 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)AT.WorkPointer,num) )
2156 ncoef = INCLENG(ncoef);
2165 if ( *t < FUNCTION ) {
2166 MLOCK(ErrorMessageLock);
2167 MesPrint(
"Illegal code in Norm");
2171 AO.OutFill = AO.OutputLine = OutBuf;
2176 while ( --i >= 0 ) {
2177 TalToLine((UWORD)(*t++));
2178 TokenToLine((UBYTE *)
" ");
2184 MUNLOCK(ErrorMessageLock);
2187 if ( *t == REPLACEMENT && ReplaceType == -1 ) {
2190 if ( AN.RSsize < 2*t[1]+SUBEXPSIZE ) {
2191 if ( AN.ReplaceScrat ) M_free(AN.ReplaceScrat,
"AN.ReplaceScrat");
2192 AN.RSsize = 2*t[1]+SUBEXPSIZE+40;
2193 AN.ReplaceScrat = (WORD *)Malloc1((AN.RSsize+1)*
sizeof(WORD),
"AN.ReplaceScrat");
2196 ReplaceSub = AN.ReplaceScrat;
2197 ReplaceSub += SUBEXPSIZE;
2199 if ( *t > 0 )
goto NoRep;
2200 if ( *t <= -FUNCTION ) {
2201 *ReplaceSub++ = FUNTOFUN;
2203 *ReplaceSub++ = -*t++;
2204 if ( *t > -FUNCTION )
goto NoRep;
2205 *ReplaceSub++ = -*t++;
2207 else if ( t+4 > r )
goto NoRep;
2209 if ( *t == -SYMBOL ) {
2210 if ( t[2] == -SYMBOL && t+4 <= r )
2211 *ReplaceSub++ = SYMTOSYM;
2212 else if ( t[2] == -SNUMBER && t+4 <= r ) {
2213 *ReplaceSub++ = SYMTONUM;
2214 if ( ReplaceType == 0 ) {
2215 oldtoprhs = C->numrhs;
2220 else if ( t[2] == ARGHEAD && t+2+ARGHEAD <= r ) {
2221 *ReplaceSub++ = SYMTONUM;
2223 *ReplaceSub++ = t[1];
2232 else if ( t[2] > 0 ) {
2233 WORD *sstop, *ttstop, n;
2237 while ( ss < sstop ) {
2239 ttstop = tt - ABS(tt[-1]);
2241 while ( ss < ttstop ) {
2242 if ( *ss == INDEX )
goto NoRep;
2248 if ( ReplaceType == 0 ) {
2249 oldtoprhs = C->numrhs;
2253 ss = AddRHS(AT.ebufnum,1);
2257 while ( (ss + n + 10) > C->
Top ) ss = DoubleCbuffer(AT.ebufnum,ss);
2258 while ( --n >= 0 ) *ss++ = *tt++;
2260 C->
rhs[C->numrhs+1] = ss;
2262 *ReplaceSub++ = subtype;
2264 *ReplaceSub++ = t[1];
2265 *ReplaceSub++ = C->numrhs;
2271 else if ( *t == -VECTOR && t+4 <= r ) {
2272 if ( t[2] == -VECTOR ) *ReplaceSub++ = VECTOVEC;
2273 else if ( t[2] == -MINVECTOR )
2274 *ReplaceSub++ = VECTOMIN;
2279 else if ( t[2] > 0 ) {
2280 WORD *sstop, *ttstop, *w, *mm, n, count;
2285 while ( ss < sstop ) {
2287 ttstop = tt - ABS(tt[-1]);
2290 while ( ss < ttstop ) {
2291 if ( *ss == INDEX ) {
2292 n = ss[1] - 2; ss += 2;
2293 while ( --n >= 0 ) {
2294 if ( *ss < MINSPEC ) count++;
2300 if ( count != 1 )
goto NoRep;
2304 if ( ReplaceType == 0 ) {
2305 oldtoprhs = C->numrhs;
2309 mm = AddRHS(AT.ebufnum,1);
2310 *ReplaceSub++ = subtype;
2312 *ReplaceSub++ = t[1];
2313 *ReplaceSub++ = C->numrhs;
2317 while ( (mm + n + 10) > C->
Top )
2318 mm = DoubleCbuffer(AT.ebufnum,mm);
2319 while ( --n >= 0 ) *mm++ = *w++;
2321 C->
rhs[C->numrhs+1] = mm;
2323 mm = AddRHS(AT.ebufnum,1);
2327 while ( (mm + n + 13) > C->
Top )
2328 mm = DoubleCbuffer(AT.ebufnum,mm);
2330 while ( w < sstop ) {
2331 tt = w + *w; ttstop = tt - ABS(tt[-1]);
2333 while ( w < ttstop ) {
2334 if ( *w != INDEX ) {
2343 while ( --n >= 0 ) {
2344 if ( *w >= MINSPEC ) *mm++ = *w++;
2349 if ( n <= 2 ) mm -= 2;
2358 while ( w < tt ) *mm++ = *w++;
2359 *ss = WORDDIF(mm,ss);
2362 C->
rhs[C->numrhs+1] = mm;
2364 if ( mm > C->
Top ) {
2365 MLOCK(ErrorMessageLock);
2366 MesPrint(
"Internal error in Normalize with extra compiler buffer");
2367 MUNLOCK(ErrorMessageLock);
2375 else if ( *t == -INDEX ) {
2376 if ( ( t[2] == -INDEX || t[2] == -VECTOR )
2378 *ReplaceSub++ = INDTOIND;
2379 else if ( t[1] >= AM.OffsetIndex ) {
2380 if ( t[2] == -SNUMBER && t+4 <= r
2381 && t[3] >= 0 && t[3] < AM.OffsetIndex )
2382 *ReplaceSub++ = INDTOIND;
2383 else if ( t[2] == ARGHEAD && t+2+ARGHEAD <= r ) {
2384 *ReplaceSub++ = INDTOIND;
2386 *ReplaceSub++ = t[1];
2397 *ReplaceSub++ = t[1];
2398 *ReplaceSub++ = t[3];
2403 AN.ReplaceScrat[1] = ReplaceSub-AN.ReplaceScrat;
2406 if ( ReplaceType > 0 ) {
2407 C->numrhs = oldtoprhs;
2417 if ( *t == DUMMYFUN || *t == DUMMYTEN ) {}
2419 if ( *t < (FUNCTION + WILDOFFSET) ) {
2420 if ( ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2421 || ( functions[*t-FUNCTION].minnumargs > 0 ) )
2422 && ( ( t[2] & DIRTYFLAG ) != 0 ) ) {
2426 WORD *ta = t + FUNHEAD, *tb = t + t[1];
2428 while ( ta < tb ) { numarg++; NEXTARG(ta) }
2429 if ( ( functions[*t-FUNCTION].maxnumargs > 0 )
2430 && ( numarg >= functions[*t-FUNCTION].maxnumargs ) )
2432 if ( ( functions[*t-FUNCTION].minnumargs > 0 )
2433 && ( numarg < functions[*t-FUNCTION].minnumargs ) )
2437 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION].tabl == 0 ) ) {
2439 t[2] |= DIRTYSYMFLAG;
2441 if ( functions[*t-FUNCTION].commute ) { pnco[nnco++] = t; }
2442 else { pcom[ncom++] = t; }
2445 if ( ( ( t[2] & DIRTYFLAG ) != 0 ) && ( functions[*t-FUNCTION-WILDOFFSET].tabl == 0 ) ) {
2447 t[2] |= DIRTYSYMFLAG;
2449 if ( functions[*t-FUNCTION-WILDOFFSET].commute ) {
2452 else { pcom[ncom++] = t; }
2458 if ( ( *t < (FUNCTION + WILDOFFSET)
2459 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) || (
2460 *t >= (FUNCTION + WILDOFFSET)
2461 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION ) ) {
2462 if ( *t >= GAMMA && *t <= GAMMASEVEN ) t++;
2465 if ( *t >= AM.OffsetIndex && ( *t >= AM.DumInd
2466 || ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2469 else if ( *t == FUNNYWILD ) { t++; }
2484 else if ( *t <= -FUNCTION ) t++;
2485 else if ( *t == -INDEX ) {
2486 if ( t[1] >= AM.OffsetIndex &&
2487 ( t[1] >= AM.DumInd || ( t[1] < AM.WilInd
2488 && indices[t[1]-AM.OffsetIndex].dimension ) ) )
2492 else if ( *t == -SYMBOL ) {
2493 if ( t[1] >= MAXPOWER && t[1] < 2*MAXPOWER ) {
2497 else if ( t[1] < -MAXPOWER && t[1] > -2*MAXPOWER ) {
2513 r = t = ANsr; m = ANsm;
2514 ANsc = ANsm = ANsr = 0;
2527 for ( k = 0, i = 0; i < nden; i++ ) {
2529 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2530 r = t + t[1]; m = t + FUNHEAD;
2532 for ( j = i+1; j < nden; j++ ) pden[j-1] = pden[j];
2534 for ( j = 0; j < nnco; j++ )
if ( pnco[j] == t )
break;
2535 for ( j++; j < nnco; j++ ) pnco[j-1] = pnco[j];
2541 if ( m >= r )
continue;
2546 k = 1; to = termout; from = term;
2548 while ( from < t ) *to++ = *from++;
2552 *to++ = DENOMINATOR;
2553 for ( j = 1; j < FUNHEAD; j++ ) *to++ = 0;
2554 if ( *m < -FUNCTION ) *to++ = *m++;
2555 else if ( *m < 0 ) { *to++ = *m++; *to++ = *m++; }
2557 j = *m;
while ( --j >= 0 ) *to++ = *m++;
2559 stop[1] = WORDDIF(to,stop);
2562 if ( i == nden - 1 ) {
2563 stop = term + *term;
2564 while ( from < stop ) *to++ = *from++;
2565 i = *termout = WORDDIF(to,termout);
2566 to = term; from = termout;
2567 while ( --i >= 0 ) *to++ = *from++;
2572 for ( i = 0; i < nden; i++ ) {
2574 if ( ( t[2] & DIRTYFLAG ) == 0 )
continue;
2576 if ( t[FUNHEAD] == -SYMBOL ) {
2579 change = ExtraSymbol(*t,-1,nsym,ppsym,&ncoef);
2581 ppsym += change << 1;
2584 else if ( t[FUNHEAD] == -SNUMBER ) {
2586 if ( *t == 0 )
goto NormInf;
2587 if ( *t < 0 ) { *AT.WorkPointer = -*t; j = -1; }
2588 else { *AT.WorkPointer = *t; j = 1; }
2589 ncoef = REDLENG(ncoef);
2590 if ( Divvy(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)AT.WorkPointer,j) )
2592 ncoef = INCLENG(ncoef);
2595 else if ( t[FUNHEAD] == ARGHEAD )
goto NormInf;
2596 else if ( t[FUNHEAD] > 0 && t[FUNHEAD+ARGHEAD] ==
2597 t[FUNHEAD]-ARGHEAD ) {
2600 t += FUNHEAD + ARGHEAD + 1;
2602 m = r - ABS(*r) + 1;
2603 if ( j != 3 || ( ( *m != 1 ) || ( m[1] != 1 ) ) ) {
2604 ncoef = REDLENG(ncoef);
2605 if ( DivRat(BHEAD (UWORD *)AT.n_coef,ncoef,(UWORD *)m,REDLENG(j),(UWORD *)AT.n_coef,&ncoef) )
goto FromNorm;
2606 ncoef = INCLENG(ncoef);
2608 t[-FUNHEAD-ARGHEAD] -= j;
2616 if ( *t == SYMBOL || *t == DOTPRODUCT ) {
2619 pden[i][FUNHEAD] -= k;
2620 pden[i][FUNHEAD+ARGHEAD] -= k;
2625 if ( *t == SYMBOL ) {
2629 change = ExtraSymbol(*t,-t[1],nsym,ppsym,&ncoef);
2631 ppsym += change << 1;
2644 while ( to < stop ) *to++ = *from++;
2649 if ( pden[i][1] == 4+FUNHEAD+ARGHEAD ) {
2651 for ( j = 0; j < nnco; j++ ) {
2652 if ( pden[i] == pnco[j] ) {
2654 while ( j < nnco ) {
2655 pnco[j] = pnco[j+1];
2661 pden[i--] = pden[--nden];
2672 for ( i = 0; i < ndel; i += 2 ) {
2673 if ( t[0] == t[1] ) {
2674 if ( t[0] == EMPTYINDEX ) {}
2675 else if ( *t < AM.OffsetIndex ) {
2676 k = AC.FixIndices[*t];
2677 if ( k < 0 ) { j = -1; k = -k; }
2678 else if ( k > 0 ) j = 1;
2682 else if ( *t >= AM.DumInd ) {
2684 if ( k )
goto docontract;
2686 else if ( *t >= AM.WilInd ) {
2687 k = indices[*t-AM.OffsetIndex-WILDOFFSET].dimension;
2688 if ( k )
goto docontract;
2690 else if ( ( k = indices[*t-AM.OffsetIndex].dimension ) != 0 ) {
2694 WithFix: shortnum = k;
2695 ncoef = REDLENG(ncoef);
2696 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)(&shortnum),j) )
2698 ncoef = INCLENG(ncoef);
2702 change = ExtraSymbol((WORD)(-k),(WORD)1,nsym,ppsym,&ncoef);
2704 ppsym += change << 1;
2706 t[1] = pdel[ndel-1];
2707 t[0] = pdel[ndel-2];
2714 if ( *t < AM.OffsetIndex && t[1] < AM.OffsetIndex )
goto NormZero;
2715 j = *t - AM.OffsetIndex;
2716 if ( j >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
2717 || ( *t < AM.WilInd && indices[j].dimension ) ) ) {
2718 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2721 *m++ = pdel[ndel-2];
2725 else if ( *t == m[1] ) {
2727 *m++ = pdel[ndel-2];
2733 j = t[1]-AM.OffsetIndex;
2734 if ( j >= 0 && ( ( t[1] >= AM.DumInd && AC.lDefDim )
2735 || ( t[1] < AM.WilInd && indices[j].dimension ) ) ) {
2736 for ( j = i + 2, m = pdel+j; j < ndel; j += 2, m += 2 ) {
2739 *m++ = pdel[ndel-2];
2743 else if ( t[1] == m[1] ) {
2745 *m++ = pdel[ndel-2];
2757 for ( i = 0; i < ndel; i++ ) {
2758 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2759 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2761 for ( j = 1; j < nvec; j += 2 ) {
2765 *t-- = pdel[--ndel];
2770 t[1] = pdel[--ndel];
2773 *t-- = pdel[--ndel];
2782 if ( ndel > 0 && ncon ) {
2784 for ( i = 0; i < ndel; i++ ) {
2785 if ( *t >= AM.OffsetIndex && ( ( *t >= AM.DumInd && AC.lDefDim ) ||
2786 ( *t < AM.WilInd && indices[*t-AM.OffsetIndex].dimension ) ) ) {
2787 for ( j = 0; j < ncon; j++ ) {
2788 if ( *pcon[j] == *t ) {
2791 *t-- = pdel[--ndel];
2796 t[1] = pdel[--ndel];
2799 *t-- = pdel[--ndel];
2802 for ( j = 0; j < nnco; j++ ) {
2804 if ( r > m && r < m+m[1] ) {
2805 m[2] |= DIRTYSYMFLAG;
2809 for ( j = 0; j < ncom; j++ ) {
2811 if ( r > m && r < m+m[1] ) {
2812 m[2] |= DIRTYSYMFLAG;
2816 for ( j = 0; j < neps; j++ ) {
2818 if ( r > m && r < m+m[1] ) {
2819 m[2] |= DIRTYSYMFLAG;
2834 for ( i = 3; i < nvec; i += 2 ) {
2835 k = *t - AM.OffsetIndex;
2836 if ( k >= 0 && ( ( *t > AM.DumInd && AC.lDefDim )
2837 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
2839 for ( j = i; j < nvec; j += 2 ) {
2845 *r-- = pvec[--nvec];
2847 *t-- = pvec[--nvec];
2848 *t-- = pvec[--nvec];
2857 if ( nvec > 0 && ncon ) {
2859 for ( i = 1; i < nvec; i += 2 ) {
2860 k = *t - AM.OffsetIndex;
2861 if ( k >= 0 && ( ( *t >= AM.DumInd && AC.lDefDim )
2862 || ( *t < AM.WilInd && indices[k].dimension ) ) ) {
2863 for ( j = 0; j < ncon; j++ ) {
2864 if ( *pcon[j] == *t ) {
2866 *t-- = pvec[--nvec];
2867 *t-- = pvec[--nvec];
2869 pcon[j] = pcon[--ncon];
2871 for ( j = 0; j < nnco; j++ ) {
2873 if ( r > m && r < m+m[1] ) {
2874 m[2] |= DIRTYSYMFLAG;
2878 for ( j = 0; j < ncom; j++ ) {
2880 if ( r > m && r < m+m[1] ) {
2881 m[2] |= DIRTYSYMFLAG;
2885 for ( j = 0; j < neps; j++ ) {
2887 if ( r > m && r < m+m[1] ) {
2888 m[2] |= DIRTYSYMFLAG;
2906 for ( i = 0; i < nnco; i++ ) {
2908 if ( ( *t >= (FUNCTION+WILDOFFSET)
2909 && functions[*t-FUNCTION-WILDOFFSET].spec == 0 )
2910 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
2911 && functions[*t-FUNCTION].spec == 0 ) ) {
2917 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
2920 pnco[i][2] |= DIRTYSYMFLAG;
2932 for ( i = 0; i < nnco; i++ ) {
2934 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) && *t != DOLLAREXPRESSION ) {
2936 if ( ( *t >= (FUNCTION+WILDOFFSET)
2937 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
2938 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
2939 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
2940 if ( *t >= (FUNCTION+WILDOFFSET) ) {
2942 j = FullSymmetrize(BHEAD t,l);
2945 else j = FullSymmetrize(BHEAD t,l);
2946 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
2947 if ( ( j & 2 ) != 0 )
goto NormZero;
2948 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
2951 else t[2] &= ~DIRTYSYMFLAG;
2959 for ( i = 0; i < k; i++ ) {
2961 while ( Commute(pnco[j],pnco[j+1]) ) {
2962 t = pnco[j]; pnco[j] = pnco[j+1]; pnco[j+1] = t;
2964 while ( l >= 0 && Commute(pnco[l],pnco[l+1]) ) {
2965 t = pnco[l]; pnco[l] = pnco[l+1]; pnco[l+1] = t;
2968 if ( ++j >= k )
break;
2975 for ( i = 0; i < nnco; i++ ) {
2977 if ( *t >= GAMMA && *t <= GAMMASEVEN ) {
2983 *m++ = stype = t[FUNHEAD];
2988 if ( *t == GAMMAFIVE ) {
2989 gtype = GAMMA5; t += FUNHEAD;
goto onegammamatrix; }
2990 else if ( *t == GAMMASIX ) {
2991 gtype = GAMMA6; t += FUNHEAD;
goto onegammamatrix; }
2992 else if ( *t == GAMMASEVEN ) {
2993 gtype = GAMMA7; t += FUNHEAD;
goto onegammamatrix; }
2998 if ( gtype == GAMMA5 ) {
2999 if ( j == GAMMA1 ) j = GAMMA5;
3000 else if ( j == GAMMA5 ) j = GAMMA1;
3001 else if ( j == GAMMA7 ) ncoef = -ncoef;
3002 if ( nnum & 1 ) ncoef = -ncoef;
3004 else if ( gtype == GAMMA6 || gtype == GAMMA7 ) {
3006 if ( gtype == GAMMA6 ) gtype = GAMMA7;
3007 else gtype = GAMMA6;
3009 if ( j == GAMMA1 ) j = gtype;
3010 else if ( j == GAMMA5 ) {
3012 if ( j == GAMMA7 ) ncoef = -ncoef;
3014 else if ( j != gtype )
goto NormZero;
3017 ncoef = REDLENG(ncoef);
3018 if ( Mully(BHEAD (UWORD *)AT.n_coef,&ncoef,(UWORD *)(&shortnum),1) )
goto FromNorm;
3019 ncoef = INCLENG(ncoef);
3023 *m++ = gtype; nnum++;
3028 }
while ( ( ++i < nnco ) && ( *(t = pnco[i]) >= GAMMA
3029 && *t <= GAMMASEVEN ) && ( t[FUNHEAD] == stype ) );
3032 k = WORDDIF(m,to) - FUNHEAD-1;
3035 while ( --k >= 0 ) *from-- = *--r;
3038 to[1] = WORDDIF(m,to);
3040 else if ( *t < 0 ) {
3041 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3056 for ( i = 0; i < ncom; i++ ) {
3058 if ( ( *t >= (FUNCTION+WILDOFFSET)
3059 && functions[*t-FUNCTION-WILDOFFSET].spec == 0 )
3060 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3061 && functions[*t-FUNCTION].spec == 0 ) ) {
3067 if ( *r == -INDEX && r[1] >= 0 && r[1] < AM.OffsetIndex ) {
3070 pcom[i][2] |= DIRTYSYMFLAG;
3080 for ( i = 0; i < ncom; i++ ) {
3082 if ( *t > 0 && ( t[2] & DIRTYSYMFLAG ) ) {
3084 if ( ( *t >= (FUNCTION+WILDOFFSET)
3085 && ( l = functions[*t-FUNCTION-WILDOFFSET].symmetric ) > 0 )
3086 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3087 && ( l = functions[*t-FUNCTION].symmetric ) > 0 ) ) {
3088 if ( *t >= (FUNCTION+WILDOFFSET) ) {
3090 j = FullSymmetrize(BHEAD t,l);
3093 else j = FullSymmetrize(BHEAD t,l);
3094 if ( (l & ~REVERSEORDER) == ANTISYMMETRIC ) {
3095 if ( ( j & 2 ) != 0 )
goto NormZero;
3096 if ( ( j & 1 ) != 0 ) ncoef = -ncoef;
3099 else t[2] &= ~DIRTYSYMFLAG;
3108 for ( i = 1; i < ncom; i++ ) {
3109 for ( j = i; j > 0; j-- ) {
3115 if ( *r < 0 ) {
if ( *t >= *r )
goto NextI; }
3116 else {
if ( -*t <= *r )
goto NextI; }
3119 else if ( *r < 0 ) {
3120 if ( *t < -*r )
goto NextI;
3123 else if ( *t != *r ) {
3124 if ( *t < *r )
goto NextI;
3125 jexch: t = pcom[j]; pcom[j] = pcom[jj]; pcom[jj] = t;
3128 if ( AC.properorderflag ) {
3129 if ( ( *t >= (FUNCTION+WILDOFFSET)
3130 && functions[*t-FUNCTION-WILDOFFSET].spec >= TENSORFUNCTION )
3131 || ( *t >= FUNCTION && *t < (FUNCTION + WILDOFFSET)
3132 && functions[*t-FUNCTION].spec >= TENSORFUNCTION ) ) {}
3134 WORD *s1, *s2, *ss1, *ss2;
3135 s1 = t+FUNHEAD; s2 = r+FUNHEAD;
3136 ss1 = t + t[1]; ss2 = r + r[1];
3137 while ( s1 < ss1 && s2 < ss2 ) {
3139 if ( k > 0 )
goto jexch;
3140 if ( k < 0 )
goto NextI;
3144 if ( s1 < ss1 ) goto jexch;
3148 kk = r[1] - FUNHEAD;
3151 while ( k > 0 && kk > 0 ) {
3152 if ( *t < *r )
goto NextI;
3153 else if ( *t++ > *r++ )
goto jexch;
3156 if ( k > 0 )
goto jexch;
3162 kk = r[1] - FUNHEAD;
3165 while ( k > 0 && kk > 0 ) {
3166 if ( *t < *r )
goto NextI;
3167 else if ( *t++ > *r++ )
goto jexch;
3170 if ( k > 0 )
goto jexch;
3176 for ( i = 0; i < ncom; i++ ) {
3178 if ( *t == THETA || *t == THETA2 ) {
3179 if ( ( k = DoTheta(BHEAD t) ) == 0 )
goto NormZero;
3185 else if ( *t == DELTA2 || *t == DELTAP ) {
3186 if ( ( k = DoDelta(t) ) == 0 )
goto NormZero;
3192 else if ( *t == AR.PolyFun ) {
3193 if ( AR.PolyFunType == 1 ) {
3194 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3195 t[1] == FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER )
goto NormZero;
3196 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3200 else if ( AR.PolyFunType == 2 ) {
3204 if ( t[FUNHEAD+1] == 0 && AR.Eside != LHSIDE &&
3205 t[1] > FUNHEAD + 2 && t[FUNHEAD] == -SNUMBER ) {
3206 u = t + FUNHEAD + 2;
3208 if ( *u <= -FUNCTION ) {}
3209 else if ( t[1] == FUNHEAD+4 && t[FUNHEAD+2] == -SNUMBER
3210 && t[FUNHEAD+3] == 0 )
goto NormPRF;
3211 else if ( t[1] == FUNHEAD+4 )
goto NormZero;
3213 else if ( t[1] == *u+FUNHEAD+2 )
goto NormZero;
3215 if ( i > 0 && pcom[i-1][0] == AR.PolyFun ) AN.PolyNormFlag = 1;
3220 else if ( *t > 0 ) {
3225 *m++ = -*t; *m++ = FUNHEAD; *m++ = 0;
3236 for ( i = 0; i < neps; i++ ) {
3238 if ( ( t[2] & DIRTYSYMFLAG ) != DIRTYSYMFLAG )
continue;
3239 t[2] &= ~DIRTYSYMFLAG;
3240 if ( AR.Eside == LHSIDE || AR.Eside == LHSIDEX ) {
3249 if ( *r != FUNNYWILD ) { r++;
continue; }
3250 k = r[1]; u = r + 2;
3253 if ( *u != FUNNYWILD ) ncoef = -ncoef;
3256 tt[-2] = FUNNYWILD; tt[-1] = k; m -= 2;
3260 for ( r = t + 1; r < m; r++ ) {
3261 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3262 else if ( *r == *t )
goto NormZero;
3267 for ( r = t + 2; r < tt; r += 2 ) {
3268 if ( r[1] < t[1] ) {
3269 k = r[1]; r[1] = t[1]; t[1] = k; ncoef = -ncoef; }
3270 else if ( r[1] == t[1] )
goto NormZero;
3279 for ( r = t + 1; r < m; r++ ) {
3280 if ( *r < *t ) { k = *r; *r = *t; *t = k; ncoef = -ncoef; }
3281 else if ( *r == *t )
goto NormZero;
3290 for ( i = 0; i < (neps-1); i++ ) {
3292 for ( j = i+1; j < neps; j++ ) {
3294 if ( t[1] > r[1] ) {
3295 peps[i] = m = r; peps[j] = r = t; t = m;
3297 else if ( t[1] == r[1] ) {
3303 m = peps[j]; peps[j] = t; peps[i] = t = m;
3306 else if ( *r++ > *m++ )
break;
3307 }
while ( --k > 0 );
3312 for ( i = 0; i < neps; i++ ) {
3324 for ( i = 0; i < ndel; i += 2, r += 2 ) {
3325 if ( r[1] < r[0] ) { k = *r; *r = r[1]; r[1] = k; }
3327 for ( i = 2; i < ndel; i += 2, t += 2 ) {
3329 for ( j = i; j < ndel; j += 2 ) {
3330 if ( *r > *t ) { r += 2; }
3331 else if ( *r < *t ) {
3332 k = *r; *r++ = *t; *t++ = k;
3333 k = *r; *r++ = *t; *t-- = k;
3336 if ( *++r < t[1] ) {
3337 k = *r; *r = t[1]; t[1] = k;
3355 for ( i = 0; i < nind; i++ ) {
3357 for ( j = i+1; j < nind; j++ ) {
3359 k = *r; *r = *t; *t = k;
3377 for ( i = 2; i < nvec; i += 2 ) {
3379 for ( j = i; j < nvec; j += 2 ) {
3381 if ( *++r < t[1] ) {
3382 k = *r; *r = t[1]; t[1] = k;
3386 else if ( *r < *t ) {
3387 k = *r; *r++ = *t; *t++ = k;
3388 k = *r; *r++ = *t; *t-- = k;
3408 while ( --i >= 0 ) {
3409 if ( *t > t[1] ) { j = *t; *t = t[1]; t[1] = j; }
3415 while ( t < (m-3) ) {
3419 if ( *++r == *++t ) {
3421 if ( ( *r < MAXPOWER && t[1] < MAXPOWER )
3422 || ( *r > -MAXPOWER && t[1] > -MAXPOWER ) ) {
3425 if ( *t > MAXPOWER || *t < -MAXPOWER ) {
3426 MLOCK(ErrorMessageLock);
3427 MesPrint(
"Exponent of dotproduct out of range: %d",*t);
3428 MUNLOCK(ErrorMessageLock);
3444 else if ( *r < *++t ) {
3445 k = *r; *r++ = *t; *t = k;
3450 else if ( *r < *t ) {
3451 k = *r; *r++ = *t; *t++ = k;
3452 k = *r; *r++ = *t; *t = k;
3455 else { r += 2; t--; }
3457 else if ( *r < *t ) {
3458 k = *r; *r++ = *t; *t++ = k;
3459 k = *r; *r++ = *t; *t++ = k;
3460 k = *r; *r++ = *t; *t = k;
3469 if ( ( i = ndot ) > 0 ) {
3484 *m++ = ( i = nsym ) + 2;
3487 if ( t[1] < (2*MAXPOWER) ) {
3488 if ( t[1] & 1 ) { *m++ = 0; *m++ = 1; }
3490 if ( *++t & 2 ) ncoef = -ncoef;
3494 else if ( *t <= NumSymbols && *t > -2*MAXPOWER ) {
3495 if ( ( ( ( t[1] > symbols[*t].maxpower ) && ( symbols[*t].maxpower < MAXPOWER ) ) ||
3496 ( ( t[1] < symbols[*t].minpower ) && ( symbols[*t].minpower > -MAXPOWER ) ) ) &&
3497 ( t[1] < 2*MAXPOWER ) && ( t[1] > -2*MAXPOWER ) ) {
3498 if ( i <= 2 || t[2] != *t )
goto NormZero;
3500 if ( AN.ncmod == 1 && ( AC.modmode & ALSOPOWERS ) != 0 ) {
3501 if ( AC.cmod[0] == 1 ) t[1] = 0;
3502 else if ( t[1] >= 0 ) t[1] = 1 + (t[1]-1)%(AC.cmod[0]-1);
3504 t[1] = -1 - (-t[1]-1)%(AC.cmod[0]-1);
3505 if ( t[1] < 0 ) t[1] += (AC.cmod[0]-1);
3508 if ( ( t[1] < (2*MAXPOWER) && t[1] >= MAXPOWER )
3509 || ( t[1] > -(2*MAXPOWER) && t[1] <= -MAXPOWER ) ) {
3510 MLOCK(ErrorMessageLock);
3511 MesPrint(
"Exponent out of range: %d",t[1]);
3512 MUNLOCK(ErrorMessageLock);
3519 else { *r -= 2; t += 2; }
3522 *m++ = *t++; *m++ = *t++;
3524 }
while ( (i-=2) > 0 ); }
3525 if ( *r <= 2 ) m = r-1;
3531 stop = (WORD *)(((UBYTE *)(termout)) + AM.MaxTer);
3533 if ( ( m + i ) > stop ) {
3534 MLOCK(ErrorMessageLock);
3535 MesPrint(
"Term too complex during normalization");
3536 MUNLOCK(ErrorMessageLock);
3539 if ( ReplaceType >= 0 ) {
3546 if ( ReplaceType == 0 ) {
3547 AT.WorkPointer = termout+*termout;
3548 WildFill(BHEAD term,termout,AN.ReplaceScrat);
3549 termout = term + *term;
3552 AT.WorkPointer = r = termout + *termout;
3553 WildFill(BHEAD r,termout,AN.ReplaceScrat);
3560 r += *term; r -= ABS(r[-1]);
3563 if ( *m > FUNCTION && m[1] > FUNHEAD &&
3564 functions[*m-FUNCTION].spec != TENSORFUNCTION )
3588 #ifdef OLDNORMREPLACE 3590 WORD oldpolynorm = AN.PolyNormFlag;
3591 WORD *oldcterm = AN.cTerm, *tstop, *argstop, *rnext, *tt, *wt;
3592 WORD *oldwork, olddefer;
3593 LONG newspace, oldspace, numterms;
3594 AT.WorkPointer = termout;
3595 if ( AT.WorkPointer < term + *term && term >= AT.WorkSpace
3596 && term < AT.WorkTop ) AT.WorkPointer = term + *term;
3603 tstop = term + *term; tstop -= ABS(tstop[-1]);
3605 while ( t < tstop ) {
3606 if ( *t >= FUNCTION && ( ( t[2] & DIRTYFLAG ) != 0 )
3607 && ( functions[*t-FUNCTION].spec == 0 ) ) {
3608 VOID *oldcompareroutine = AR.CompareRoutine;
3609 r = t + FUNHEAD; argstop = t + t[1];
3610 while ( r < argstop ) {
3611 if ( *r > 0 && ( r[1] != 0 ) ) {
3612 m = r + ARGHEAD; rnext = r + *r;
3613 oldwork = AT.WorkPointer;
3614 olddefer = AR.DeferFlag;
3616 if ( *t == AR.PolyFun && AR.PolyFunType == 2 ) {
3620 m = r + ARGHEAD; rnext = r + *r;
3621 while ( m < rnext ) {
3622 i = *m; tt = m; wt = oldwork;
3624 AT.WorkPointer = wt;
3625 if (
Generator(BHEAD oldwork,AR.Cnumlhs) ) {
3630 AT.WorkPointer = (WORD *)(((UBYTE *)(oldwork)) + AM.MaxTer);
3631 if ( AT.WorkPointer > AT.WorkTop )
goto OverWork;
3633 if (
EndSort(BHEAD m,1) < 0 )
goto FromNorm;
3634 if ( *t == AR.PolyFun && AR.PolyFunType == 2 ) {
3635 AR.CompareRoutine = oldcompareroutine;
3641 AR.DeferFlag = olddefer;
3642 numterms = 0; wt = m;
3643 while ( *wt ) { numterms++; wt += *wt; }
3645 oldspace = *r - ARGHEAD;
3649 if ( numterms == 0 ) {
3650 m[0] = -SNUMBER; m[1] = 0;
3653 else if ( numterms == 1 ) {
3654 if ( *m == 4+FUNHEAD && m[3+FUNHEAD] == 3
3655 && m[2+FUNHEAD] == 1 && m[1+FUNHEAD] == 1
3656 && m[1] >= FUNCTION ) {
3660 else if ( *m == 8 && m[7] == 3
3661 && m[6] == 1 && m[5] == 1
3662 && m[1] == SYMBOL && m[4] == 1 ) {
3663 m[0] = -SYMBOL; m[1] = m[3];
3666 else if ( *m == 7 && m[6] == 3
3667 && m[5] == 1 && m[4] == 1
3668 && m[1] == INDEX ) {
3670 m[0] = -INDEX; m[1] = m[3];
3673 m[0] = -VECTOR; m[1] = m[3];
3677 else if ( *m == 7 && m[6] == -3
3678 && m[5] == 1 && m[4] == 1
3679 && m[1] == INDEX && m[3] < 0 ) {
3680 m[0] = -MINVECTOR; m[1] = m[3];
3684 && m[2] == 1 && (UWORD)(m[1]) <= MAXPOSITIVE ) {
3686 if ( m[3] < 0 ) m[1] = -m[1];
3697 if ( newspace <= 2 ) {
3699 i = oldspace - newspace;
3701 if ( newspace > 1 ) r[1] = m[1];
3705 while ( wt < tt ) *m++ = *wt++;
3711 else if ( oldspace == newspace ) {
3712 i = newspace; tt = r+ARGHEAD; wt = m;
3716 else if ( oldspace > newspace ) {
3717 i = newspace; tt = r+ARGHEAD; wt = m;
3719 wt = rnext; m = term + *term;
3720 while ( wt < m ) *tt++ = *wt++;
3721 i = oldspace - newspace;
3729 else if ( (*term+newspace-oldspace)*
sizeof(WORD) > AM.MaxTer ) {
3730 MLOCK(ErrorMessageLock);
3731 MesPrint(
"Term too complex. Maybe increasing MaxTermSize can help");
3733 MUNLOCK(ErrorMessageLock);
3737 i = newspace - oldspace;
3738 tt = term + *term; wt = rnext;
3739 while ( tt > rnext ) { tt--; tt[i] = tt[0]; }
3745 i = newspace; tt = r+ARGHEAD; wt = m;
3749 AT.WorkPointer = oldwork;
3754 if ( *t >= FUNCTION && ( t[2] & DIRTYFLAG ) != 0 ) {
3756 if ( functions[*t-FUNCTION].symmetric ) t[2] |= DIRTYSYMFLAG;
3761 AN.PolyNormFlag = oldpolynorm;
3762 AN.cTerm = oldcterm;
3765 WORD *oldwork = AT.WorkPointer;
3766 WORD olddefer = AR.DeferFlag;
3769 if (
Generator(BHEAD term,AR.Cnumlhs) ) {
3772 AT.WorkPointer = oldwork;
3773 if (
EndSort(BHEAD term,1) < 0 )
goto FromNorm;
3774 if ( *term == 0 )
goto NormZero;
3775 AR.DeferFlag = olddefer;
3781 #ifdef OLDNORMREPLACE 3782 AT.WorkPointer = termout;
3783 if ( ReplaceType == 0 ) {
3810 AT.WorkPointer = termout;
3811 if ( termout < term + *term && termout >= term ) AT.WorkPointer = term + *term;
3820 MLOCK(ErrorMessageLock);
3821 MesPrint(
"Division by zero during normalization");
3822 MUNLOCK(ErrorMessageLock);
3826 MLOCK(ErrorMessageLock);
3827 MesPrint(
"0^0 during normalization of term");
3828 MUNLOCK(ErrorMessageLock);
3832 MLOCK(ErrorMessageLock);
3833 MesPrint(
"0/0 in polyratfun during normalization of term");
3834 MUNLOCK(ErrorMessageLock);
3839 AT.WorkPointer = termout;
3846 MLOCK(ErrorMessageLock);
3848 MUNLOCK(ErrorMessageLock);
3851 #ifdef OLDNORMREPLACE 3853 MLOCK(ErrorMessageLock);
3856 MUNLOCK(ErrorMessageLock);
3870 WORD ExtraSymbol(WORD sym, WORD pow, WORD nsym, WORD *ppsym, WORD *ncoef)
3878 if ( pow > 2*MAXPOWER || pow < -2*MAXPOWER
3879 || *m > 2*MAXPOWER || *m < -2*MAXPOWER ) {
3880 MLOCK(ErrorMessageLock);
3881 MesPrint(
"Illegal wildcard power combination.");
3882 MUNLOCK(ErrorMessageLock);
3887 if ( ( sym <= NumSymbols && sym > -MAXPOWER )
3888 && ( symbols[sym].complex & VARTYPEROOTOFUNITY ) == VARTYPEROOTOFUNITY ) {
3889 *m %= symbols[sym].maxpower;
3890 if ( *m < 0 ) *m += symbols[sym].maxpower;
3891 if ( ( symbols[sym].complex & VARTYPEMINUS ) == VARTYPEMINUS ) {
3892 if ( ( ( symbols[sym].maxpower & 1 ) == 0 ) &&
3893 ( *m >= symbols[sym].maxpower/2 ) ) {
3894 *m -= symbols[sym].maxpower/2; *ncoef = -*ncoef;
3899 if ( *m >= 2*MAXPOWER || *m <= -2*MAXPOWER ) {
3900 MLOCK(ErrorMessageLock);
3901 MesPrint(
"Power overflow during normalization");
3902 MUNLOCK(ErrorMessageLock);
3908 { *m = m[2]; m++; *m = m[2]; m++; i++; }
3913 else if ( sym < *m ) {
3921 { m--; m[2] = *m; m--; m[2] = *m; i++; }
3932 WORD DoTheta(
PHEAD WORD *t)
3935 WORD k, *r1, *r2, *tstop, type;
3936 WORD ia, *ta, *tb, *stopa, *stopb;
3937 if ( AC.BracketNormalize )
return(-1);
3942 if ( k <= FUNHEAD )
return(1);
3945 if ( r1 == tstop ) {
3949 if ( *t == ARGHEAD ) {
3950 if ( type == THETA )
return(1);
3954 if ( *t == -SNUMBER ) {
3955 if ( t[1] < 0 )
return(0);
3957 if ( type == THETA2 && t[1] == 0 )
return(0);
3964 if ( *t == ABS(k)+1+ARGHEAD ) {
3965 if ( k > 0 )
return(1);
3975 if ( r2 < tstop ) return(-1);
3980 if ( *t == -SNUMBER && *r1 == -SNUMBER ) {
3981 if ( t[1] > r1[1] )
return(0);
3982 else if ( t[1] < r1[1] ) {
3985 else if ( type == THETA )
return(1);
3988 else if ( t[1] == 0 && *t == -SNUMBER ) {
3990 else if ( *t < *r1 )
return(1);
3991 else if ( *t > *r1 )
return(0);
3993 else if ( r1[1] == 0 && *r1 == -SNUMBER ) {
3995 else if ( *t < *r1 )
return(1);
3996 else if ( *t > *r1 )
return(0);
3998 r2 = AT.WorkPointer;
4012 ta += ARGHEAD; tb += ARGHEAD;
4013 while ( ta < stopa ) {
4014 if ( tb >= stopb )
return(0);
4015 if ( ( ia = CompareTerms(BHEAD ta,tb,(WORD)1) ) < 0 )
return(0);
4016 if ( ia > 0 )
return(1);
4020 if ( type == THETA )
return(1);
4029 WORD DoDelta(WORD *t)
4031 WORD k, *r1, *r2, *tstop, isnum, isnum2, type = *t;
4032 if ( AC.BracketNormalize )
return(-1);
4034 if ( k <= FUNHEAD )
goto argzero;
4035 if ( k == FUNHEAD+ARGHEAD && t[FUNHEAD] == ARGHEAD )
goto argzero;
4042 if ( *t == -SNUMBER ) { isnum = 1; k = t[1]; }
4048 if ( k == *t-ARGHEAD-1 ) isnum = 1;
4052 if ( r1 >= tstop ) {
4053 if ( !isnum )
return(-1);
4054 if ( k == 0 )
goto argzero;
4059 if ( r2 < tstop ) return(-1);
4061 if ( *r1 == -SNUMBER ) { isnum2 = 1; }
4067 if ( k == *r1-ARGHEAD-1 ) isnum2 = 1;
4070 if ( isnum != isnum2 )
return(-1);
4072 while ( t < tstop && r1 < r2 ) {
4074 if ( !isnum )
return(-1);
4079 if ( t != tstop || r1 != r2 ) {
4080 if ( !isnum )
return(-1);
4084 if ( type == DELTA2 )
return(1);
4087 if ( type == DELTA2 )
return(0);
4096 void DoRevert(WORD *fun, WORD *tmp)
4098 WORD *t, *r, *m, *to, *tt, *mm, i, j;
4103 if ( *r == -REVERSEFUNCTION ) {
4105 while ( mm < to ) *m++ = *mm++;
4108 fun[2] |= DIRTYSYMFLAG;
4110 else if ( *r <= -FUNCTION ) r++;
4112 if ( *r == -INDEX && r[1] < MINSPEC ) *r = -VECTOR;
4117 if ( ( *r > ARGHEAD )
4118 && ( r[ARGHEAD+1] == REVERSEFUNCTION )
4119 && ( *r == (r[ARGHEAD]+ARGHEAD) )
4120 && ( r[ARGHEAD] == (r[ARGHEAD+2]+4) )
4121 && ( *(r+*r-3) == 1 )
4122 && ( *(r+*r-2) == 1 )
4123 && ( *(r+*r-1) == 3 ) ) {
4135 while ( --j >= 0 ) {
4138 while ( --i >= 0 ) {
4145 else if ( *t <= -FUNCTION ) *m++ = *t++;
4146 else { *m++ = *t++; *m++ = *t++; }
4157 fun[1] = WORDDIF(t,fun);
4159 fun[2] |= DIRTYSYMFLAG;
4182 #define MAXNUMBEROFNONCOMTERMS 2 4184 WORD DetCommu(WORD *terms)
4186 WORD *t, *tnext, *tstop;
4188 if ( *terms == 0 )
return(0);
4189 if ( terms[*terms] == 0 )
return(0);
4193 tstop = tnext - ABS(tnext[-1]);
4195 while ( t < tstop ) {
4196 if ( *t >= FUNCTION ) {
4197 if ( functions[*t-FUNCTION].commute ) {
4199 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4203 else if ( *t == SUBEXPRESSION ) {
4204 if ( cbuf[t[4]].CanCommu[t[2]] ) {
4206 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4210 else if ( *t == EXPRESSION ) {
4212 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4215 else if ( *t == DOLLAREXPRESSION ) {
4222 if ( cbuf[AM.dbufnum].CanCommu[t[2]] ) {
4224 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4243 WORD DoesCommu(WORD *term)
4247 if ( *term == 0 )
return(0);
4248 tstop = term + *term;
4249 tstop = tstop - ABS(tstop[-1]);
4251 while ( term < tstop ) {
4252 if ( ( *term >= FUNCTION ) && ( functions[*term-FUNCTION].commute ) ) {
4254 if ( num >= MAXNUMBEROFNONCOMTERMS )
return(num);
4269 WORD *PolyNormPoly (
PHEAD WORD *Poly) {
4272 WORD *buffer = AT.WorkPointer;
4274 if (
NewSort(BHEAD0) ) { Terminate(-1); }
4280 AR.CompareRoutine = (
void *)&
Compare1;
4286 if (
EndSort(BHEAD buffer,1) < 0 ) {
4287 AR.CompareRoutine = (
void *)&
Compare1;
4291 while ( *p ) p += *p;
4292 AR.CompareRoutine = (
void *)&
Compare1;
4293 AT.WorkPointer = p + 1;
4320 WORD *EvaluateGcd(
PHEAD WORD *subterm)
4323 WORD *oldworkpointer = AT.WorkPointer, *work1, *work2, *work3;
4324 WORD *t, *tt, *ttt, *t1, *t2, *t3, *t4, *tstop;
4327 WORD *lnum=AT.n_llnum+1;
4328 WORD *num1, *num2, *num3, *den1, *den2, *den3;
4329 WORD sizenum1, sizenum2, sizenum3, sizeden1, sizeden2, sizeden3;
4330 int i, isnumeric = 0, numarg = 0 ;
4336 tt = subterm + subterm[1]; t = subterm + FUNHEAD;
4340 if ( *t == -SNUMBER ) {
4343 MLOCK(ErrorMessageLock);
4344 MesPrint(
"Trying to take the GCD involving a zero term.");
4345 MUNLOCK(ErrorMessageLock);
4349 t1 = subterm + FUNHEAD;
4350 while ( gcdnum > 1 && t1 < tt ) {
4351 if ( *t1 == -SNUMBER ) {
4353 if ( stor == 0 )
goto gcdzero;
4354 if ( GcdLong(BHEAD (UWORD *)&stor,1,(UWORD *)&gcdnum,1,
4355 (UWORD *)lnum,&nnum) )
goto FromGCD;
4360 else if ( *t1 == -SYMBOL )
goto gcdisone;
4361 else if ( *t1 < 0 )
goto gcdillegal;
4367 ct = *ttt; *ttt = 0;
4369 t1 = PolyNormPoly(BHEAD t1+ARGHEAD);
4378 while ( t3 > t2 && *t3 == 0 ) { t3--; i--; }
4379 if ( GcdLong(BHEAD (UWORD *)t2,(WORD)i,(UWORD *)&gcdnum,1,
4380 (UWORD *)lnum,&nnum) ) {
4385 if ( gcdnum == 1 ) {
4392 AT.WorkPointer = oldworkpointer;
4394 if ( gcdnum == 1 )
goto gcdisone;
4395 oldworkpointer[0] = 4;
4396 oldworkpointer[1] = gcdnum;
4397 oldworkpointer[2] = 1;
4398 oldworkpointer[3] = 3;
4399 oldworkpointer[4] = 0;
4400 AT.WorkPointer = oldworkpointer + 5;
4401 return(oldworkpointer);
4403 else if ( *t == -SYMBOL ) {
4404 t1 = subterm + FUNHEAD;
4407 if ( *t1 == -SNUMBER )
goto gcdisone;
4408 if ( *t1 == -SYMBOL ) {
4409 if ( t1[1] != i )
goto gcdisone;
4412 if ( *t1 < 0 )
goto gcdillegal;
4414 ct = *ttt; *ttt = 0;
4416 t2 = PolyNormPoly(BHEAD t1+ARGHEAD);
4418 else t2 = t1 + ARGHEAD;
4422 tstop = t2 - ABS(t2[-1]);
4423 while ( t3 < tstop ) {
4424 if ( *t3 != SYMBOL ) {
4431 if ( *t4 == i && t4[1] > 0 )
goto nextterminarg;
4441 AT.WorkPointer = oldworkpointer;
4443 oldworkpointer[0] = 8;
4444 oldworkpointer[1] = SYMBOL;
4445 oldworkpointer[2] = 4;
4446 oldworkpointer[3] = t[1];
4447 oldworkpointer[4] = 1;
4448 oldworkpointer[5] = 1;
4449 oldworkpointer[6] = 1;
4450 oldworkpointer[7] = 3;
4451 oldworkpointer[8] = 0;
4452 AT.WorkPointer = oldworkpointer+9;
4453 return(oldworkpointer);
4455 else if ( *t < 0 ) {
4457 MLOCK(ErrorMessageLock);
4458 MesPrint(
"Illegal object in gcd_ function. Object not a number or a symbol.");
4459 MUNLOCK(ErrorMessageLock);
4462 else if ( ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4463 else if ( t[1] != 0 ) {
4464 ttt = t + *t; ct = *ttt; *ttt = 0;
4465 t = PolyNormPoly(BHEAD t+ARGHEAD);
4467 if ( t[*t] == 0 && ABS(t[*t-1]) == *t-ARGHEAD-1 ) isnumeric = numarg;
4468 AT.WorkPointer = oldworkpointer;
4483 AT.WorkPointer = oldworkpointer;
4485 t = subterm + FUNHEAD;
4486 for ( i = 1; i < isnumeric; i++ ) {
4490 ttt = t + *t; ct = *ttt; *ttt = 0;
4491 t = PolyNormPoly(BHEAD t+ARGHEAD);
4495 i = (ABS(t[-1])-1)/2;
4498 sizenum1 = sizeden1 = i;
4499 while ( sizenum1 > 1 && num1[sizenum1-1] == 0 ) sizenum1--;
4500 while ( sizeden1 > 1 && den1[sizeden1-1] == 0 ) sizeden1--;
4501 work1 = AT.WorkPointer+1; work2 = work1+sizenum1;
4502 for ( i = 0; i < sizenum1; i++ ) work1[i] = num1[i];
4503 for ( i = 0; i < sizeden1; i++ ) work2[i] = den1[i];
4504 num1 = work1; den1 = work2;
4505 AT.WorkPointer = work2 = work2 + sizeden1;
4506 t = subterm + FUNHEAD;
4508 ttt = t + *t; ct = *ttt; *ttt = 0;
4510 t = PolyNormPoly(BHEAD t+ARGHEAD);
4515 i = (ABS(t[-1])-1)/2;
4518 sizenum2 = sizeden2 = i;
4519 while ( sizenum2 > 1 && num2[sizenum2-1] == 0 ) sizenum2--;
4520 while ( sizeden2 > 1 && den2[sizeden2-1] == 0 ) sizeden2--;
4521 num3 = AT.WorkPointer;
4522 if ( GcdLong(BHEAD (UWORD *)num2,sizenum2,(UWORD *)num1,sizenum1,
4523 (UWORD *)num3,&sizenum3) )
goto FromGCD;
4524 sizenum1 = sizenum3;
4525 for ( i = 0; i < sizenum1; i++ ) num1[i] = num3[i];
4526 den3 = AT.WorkPointer;
4527 if ( GcdLong(BHEAD (UWORD *)den2,sizeden2,(UWORD *)den1,sizeden1,
4528 (UWORD *)den3,&sizeden3) )
goto FromGCD;
4529 sizeden1 = sizeden3;
4530 for ( i = 0; i < sizeden1; i++ ) den1[i] = den3[i];
4531 if ( sizenum1 == 1 && num1[0] == 1 && sizeden1 == 1 && den1[1] == 1 )
4536 AT.WorkPointer = work2;
4538 AT.WorkPointer = oldworkpointer;
4542 if ( sizenum1 > sizeden1 ) {
4543 while ( sizenum1 > sizeden1 ) den1[sizeden1++] = 0;
4545 else if ( sizenum1 < sizeden1 ) {
4546 while ( sizenum1 < sizeden1 ) num1[sizenum1++] = 0;
4551 if ( num1 != t ) { NCOPY(t,num1,sizenum1); }
4553 if ( den1 != t ) { NCOPY(t,den1,sizeden1); }
4558 return(oldworkpointer);
4565 t = subterm + FUNHEAD;
4566 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
4567 work2 = AT.WorkPointer;
4574 work1 = AT.WorkPointer;
4575 ttt = t + *t; ct = *ttt; *ttt = 0;
4576 t = PolyNormPoly(BHEAD t+ARGHEAD);
4577 if ( *work1 < AT.WorkPointer-work1 ) {
4586 *AT.WorkPointer++ = 0;
4592 if ( work2 != work3 ) {
4593 work1 = PolyGCD2(BHEAD work1,work2);
4595 while ( *work2 ) work2 += *work2;
4599 while ( *work2 ) work2 += *work2;
4600 size = work2 - work1 + 1;
4602 NCOPY(t,work1,size);
4604 return(oldworkpointer);
4607 oldworkpointer[0] = 4;
4608 oldworkpointer[1] = 1;
4609 oldworkpointer[2] = 1;
4610 oldworkpointer[3] = 3;
4611 oldworkpointer[4] = 0;
4612 AT.WorkPointer = oldworkpointer+5;
4613 return(oldworkpointer);
4615 MLOCK(ErrorMessageLock);
4616 MesCall(
"EvaluateGcd");
4617 MUNLOCK(ErrorMessageLock);
4628 void DropCoefficient(
PHEAD WORD *term)
4631 WORD *t = term + *term;
4633 n = t[-1]; na = ABS(n);
4635 if ( n == 3 && t[0] == 1 && t[1] == 1 )
return;
4637 t[0] = 1; t[1] = 1; t[2] = 3;
4646 void DropSymbols(
PHEAD WORD *term)
4649 WORD *tend = term + *term, *t1, *t2, *tstop;
4650 tstop = tend - ABS(tend[-1]);
4652 while ( t1 < tstop ) {
4653 if ( *t1 == SYMBOL ) {
4656 while ( t2 < tend ) *t1++ = *t2++;
4678 WORD buffer[7*NORMSIZE], *t, *b, *bb, *tt, *m, *tstop;
4681 *b++ = SYMBOL; *b++ = 2;
4683 tstop = t - ABS(t[-1]);
4685 while ( t < tstop ) {
4686 if ( *t == SYMBOL && t < tstop ) {
4687 for ( i = 2; i < t[1]; i += 2 ) {
4690 if ( bb[0] == t[i] ) {
4692 if ( bb[1] > MAXPOWER || bb[1] < -MAXPOWER ) {
4693 MLOCK(ErrorMessageLock);
4694 MesPrint(
"Power in SymbolNormalize out of range");
4695 MUNLOCK(ErrorMessageLock);
4701 bb[0] = bb[2]; bb[1] = bb[3]; bb += 2;
4706 else if ( bb[0] > t[i] ) {
4708 while ( m > bb ) { m[1] = m[-1]; m[0] = m[-2]; m -= 2; }
4717 *b++ = t[i]; *b++ = t[i+1];
4723 MLOCK(ErrorMessageLock);
4724 MesPrint(
"Illegal term in SymbolNormalize");
4725 MUNLOCK(ErrorMessageLock);
4730 buffer[1] = b - buffer;
4734 b = buffer; bb = b + b[1]; b += 3;
4737 MLOCK(ErrorMessageLock);
4738 MesPrint(
"Negative power in SymbolNormalize");
4739 MUNLOCK(ErrorMessageLock);
4750 b = buffer; tt = term + 1;
4751 if ( i > 2 ) { NCOPY(tt,b,i) }
4754 if ( i < 0 ) i = -i;
4755 *term -= (tstop-tt);
int SymbolNormalize(WORD *term)
WORD StoreTerm(PHEAD WORD *)
WORD Compare1(PHEAD WORD *, WORD *, WORD)
WORD NextPrime(PHEAD WORD)
WORD Generator(PHEAD WORD *, WORD)
int CompareSymbols(PHEAD WORD *, WORD *, WORD)
WORD CompCoef(WORD *, WORD *)
LONG EndSort(PHEAD WORD *, int)