62int RatioFind(PHEAD WORD *term, WORD *params)
67 WORD *y1, *y2, n1 = 0, n2 = 0;
81 if ( *m == x1 ) { y1 = m; n1 = m[1]; }
82 else if ( *m == x2 ) { y2 = m; n2 = m[1]; }
85 if ( !y1 || !y2 || ( n1 > 0 && n2 > 0 ) )
return(0);
87 if ( y1 > y2 ) { r = y1; y1 = y2; y2 = r; }
88 *y2 = *m; y2[1] = m[1];
90 *y1 = *m; y1[1] = m[1];
93We have to revise the code
for the second
case.
100 while ( y1 > r ) *--y2 = *--y1;
101 *m++ = SUBEXPRESSION;
107 *term += SUBEXPSIZE-4;
111 *m++ = SUBEXPRESSION;
119 *term += SUBEXPSIZE-6;
120 r = m + 6-SUBEXPSIZE;
121 do { *m++ = *r++; }
while ( r < t );
170int RatioGen(PHEAD WORD *term, WORD *params, WORD num, WORD level)
178 WORD ncoef, sign = 0;
179 coef = (UWORD *)AT.WorkPointer;
181 tstops[2] = m = t + *t;
185 if ( *t == SUBEXPRESSION && t[2] == num )
break;
189 tstops[1] = t + t[1];
206 i = n1; n1 = n2; n2 = i;
207 i = x1; x1 = x2; x2 = i;
216 AT.WorkPointer = (WORD *)(coef + 1);
218 for ( i = 0; i <= n2; i++ ) {
219 if ( BinomGen(BHEAD term,level,tstops,x1,x3,n2-n1-i,i,sign&i
220 ,coef,ncoef) )
goto RatioCall;
222 if ( Product(coef,&ncoef,j) )
goto RatioCall;
223 if ( Quotient(coef,&ncoef,i+1) )
goto RatioCall;
225 AT.WorkPointer = (WORD *)(coef + ABS(ncoef));
228 AT.WorkPointer = (WORD *)(coef);
238 AT.WorkPointer = (WORD *)(coef + 1);
240 for ( i = 0; i <= j; i++ ) {
241 if ( BinomGen(BHEAD term,level,tstops,x2,x3,n2-n1-i,i,sign&i
242 ,coef,ncoef) )
goto RatioCall;
244 if ( Product(coef,&ncoef,n1+i) )
goto RatioCall;
245 if ( Quotient(coef,&ncoef,i+1) )
goto RatioCall;
246 AT.WorkPointer = (WORD *)(coef + ABS(ncoef));
251 AT.WorkPointer = (WORD *)(coef + 1);
253 for ( i = 0; i <= j; i++ ) {
254 if ( BinomGen(BHEAD term,level,tstops,x1,x3,i-n1,n2-i,sign&(n2-i)
255 ,coef,ncoef) )
goto RatioCall;
257 if ( Product(coef,&ncoef,n2-i) )
goto RatioCall;
258 if ( Quotient(coef,&ncoef,i+1) )
goto RatioCall;
259 AT.WorkPointer = (WORD *)(coef + ABS(ncoef));
262 AT.WorkPointer = (WORD *)(coef);
277 AT.WorkPointer = (WORD *)(coef + 1);
279 for ( i = 0; i <= j; i++ ) {
280 if ( BinomGen(BHEAD term,level,tstops,x1,x3,i-n1,-n2-i,i&1
281 ,coef,ncoef) )
goto RatioCall;
283 if ( Product(coef,&ncoef,n2+i) )
goto RatioCall;
284 if ( Quotient(coef,&ncoef,i+1) )
goto RatioCall;
285 AT.WorkPointer = (WORD *)(coef + ABS(ncoef));
290 AT.WorkPointer = (WORD *)(coef + 1);
292 for ( i = 0; i <= j; i++ ) {
293 if ( BinomGen(BHEAD term,level,tstops,x2,x3,i-n2,-n1-i,n1&1
294 ,coef,ncoef) )
goto RatioCall;
296 if ( Product(coef,&ncoef,n1+i) )
goto RatioCall;
297 if ( Quotient(coef,&ncoef,i+1) )
goto RatioCall;
298 AT.WorkPointer = (WORD *)(coef + ABS(ncoef));
301 AT.WorkPointer = (WORD *)(coef);
306 MLOCK(ErrorMessageLock);
308 MUNLOCK(ErrorMessageLock);
320int BinomGen(PHEAD WORD *term, WORD level, WORD **tstops, WORD x1, WORD x2,
321 WORD pow1, WORD pow2, WORD sign, UWORD *coef, WORD ncoef)
327 termout = AT.WorkPointer;
330 do { *t++ = *r++; }
while ( r < tstops[0] );
333 if ( pow1 == 0 ) t--;
334 else { *t++ = 4; *t++ = x1; *t++ = pow1; }
336 else if ( pow1 == 0 ) {
337 *t++ = 4; *t++ = x2; *t++ = pow2;
340 *t++ = 6; *t++ = x1; *t++ = pow1; *t++ = x2; *t++ = pow2;
343 *t++ = ABS(ncoef) + 3;
345 if ( sign ) *t = -*t;
348 for ( k = 0; k < ncoef; k++ ) *t++ = coef[k];
350 do { *t++ = *r++; }
while ( r < tstops[2] );
351 *termout = WORDDIF(t,termout);
353 if ( AT.WorkPointer > AT.WorkTop ) {
354 MLOCK(ErrorMessageLock);
356 MUNLOCK(ErrorMessageLock);
362 MLOCK(ErrorMessageLock);
364 MUNLOCK(ErrorMessageLock);
367 AT.WorkPointer = termout;
395int DoSumF1(PHEAD WORD *term, WORD *params, WORD replac, WORD level)
398 WORD *termout, *t, extractbuff = AT.TMbuff;
399 WORD isum, ival, iinc;
404 if ( ( iinc > 0 && params[4] >= ival )
405 || ( iinc < 0 && params[4] <= ival ) ) {
406 isum = (params[4] - ival)/iinc + 1;
409 termout = AT.WorkPointer;
410 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
411 if ( AT.WorkPointer > AT.WorkTop ) {
412 MLOCK(ErrorMessageLock);
414 MUNLOCK(ErrorMessageLock);
418 while ( *t != SUBEXPRESSION || t[2] != replac || t[4] != extractbuff )
422 if ( params[2] < 0 ) {
423 while ( *t != INDTOIND || t[2] != -params[2] ) t += t[1];
427 while ( *t > SYMTOSUB || t[2] != params[2] ) t += t[1];
433 while ( C->
Buffer[from] ) {
434 if (
InsertTerm(BHEAD term,replac,extractbuff,C->
Buffer+from,termout,0) < 0 )
goto SumF1Call;
435 AT.WorkPointer = termout + *termout;
436 if (
Generator(BHEAD termout,level) < 0 )
goto SumF1Call;
440 }
while ( --isum > 0 );
441 AT.WorkPointer = termout;
444 MLOCK(ErrorMessageLock);
446 MUNLOCK(ErrorMessageLock);
461int Glue(PHEAD WORD *term1, WORD *term2, WORD *sub, WORD insert)
465 WORD ncoef, *t, *t1, *t2, i, nc2, nc3, old, newer;
466 coef = (UWORD *)(TermMalloc(
"Glue"));
471 old = WORDDIF(t,term1);
477 while ( --i >= 0 ) *t2++ = *t1++;
479 nc2 = WildFill(BHEAD t,term2,sub);
484 newer = WORDDIF(t,term1);
485 if ( MulRat(BHEAD (UWORD *)t,REDLENG(nc2),coef,ncoef,(UWORD *)t,&nc3) ) {
486 MLOCK(ErrorMessageLock);
488 MUNLOCK(ErrorMessageLock);
489 TermFree(coef,
"Glue");
494 *t++ = (nc3 >= 0)?i:-i;
495 *term1 = WORDDIF(t,term1);
511 TermFree(coef,
"Glue");
520int DoSumF2(PHEAD WORD *term, WORD *params, WORD replac, WORD level)
523 WORD *termout, *t, *from, *sub, *to, extractbuff = AT.TMbuff;
524 WORD isum, ival, iinc, insert, i;
528 if ( ( iinc > 0 && params[4] >= ival )
529 || ( iinc < 0 && params[4] <= ival ) ) {
530 isum = (params[4] - ival)/iinc + 1;
533 termout = AT.WorkPointer;
534 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
535 if ( AT.WorkPointer > AT.WorkTop ) {
536 MLOCK(ErrorMessageLock);
538 MUNLOCK(ErrorMessageLock);
542 while ( *t != SUBEXPRESSION || t[2] != replac || t[4] != extractbuff ) t += t[1];
543 insert = WORDDIF(t,term);
547 while ( from < t ) *to++ = *from++;
550 while ( from < sub ) *to++ = *from++;
556 if ( params[2] < 0 ) {
557 while ( *t != INDTOIND || t[2] != -params[2] ) t += t[1];
561 while ( *t > SYMTOSUB || t[2] != params[2] ) t += t[1];
566 AT.WorkPointer = termout + *termout;
568 if ( ( to + *termout ) > AT.WorkTop ) {
569 MLOCK(ErrorMessageLock);
571 MUNLOCK(ErrorMessageLock);
577 from = AT.WorkPointer;
579 if (
Generator(BHEAD from,level) < 0 )
goto SumF2Call;
580 if ( --isum <= 0 )
break;
583 if ( Glue(BHEAD termout,C->
rhs[replac],sub,insert) < 0 )
goto SumF2Call;
585 AT.WorkPointer = termout;
588 MLOCK(ErrorMessageLock);
590 MUNLOCK(ErrorMessageLock);
609int GCDfunction(PHEAD WORD *term,WORD level)
612 WORD *t, *tstop, *tf, *termout, *tin, *tout, *m, *mnext, *mstop, *mm;
613 int todo, i, ii, j, istart, sign = 1, action = 0;
614 WORD firstshort = 0, firstvalue = 0, gcdisone = 0, mlength, tlength, newlength;
615 WORD totargs = 0, numargs, argsdone = 0, *mh, oldval1, *g, *gcdout = 0;
631 t = term + *term; tlength = t[-1];
632 tstop = t - ABS(tlength);
634 while ( t < tstop ) {
635 if ( *t != GCDFUNCTION ) { t += t[1];
continue; }
636 todo = 1; totargs = 0;
638 while ( tf < t + t[1] ) {
640 if ( *tf > 0 && tf[1] != 0 ) todo = 0;
648 MLOCK(ErrorMessageLock);
649 MesPrint(
"!>Internal error. Indicated gcd_ function not encountered.");
650 MUNLOCK(ErrorMessageLock);
654 WantAddPointers(totargs);
655 args = AT.pWorkPointer; AT.pWorkPointer += totargs;
669 while ( tf < t + t[1] ) {
670 if ( *tf == -SNUMBER && tf[1] == 0 ) { NEXTARG(tf);
continue; }
671 if ( *tf > 0 || *tf == -DOLLAREXPRESSION || *tf == -EXPRESSION ) {
672 AT.pWorkSpace[args+numargs++] = tf;
673 NEXTARG(tf);
continue;
675 if ( firstshort == 0 ) {
677 if ( *tf <= -FUNCTION ) { firstvalue = -(*tf); }
678 else { firstvalue = tf[1]; }
683 else if ( *tf != firstshort ) {
684 if ( *tf != -INDEX && *tf != -VECTOR && *tf != -MINVECTOR ) {
685 argsdone++; gcdisone = 1;
break;
687 if ( firstshort != -INDEX && firstshort != -VECTOR && firstshort != -MINVECTOR ) {
688 argsdone++; gcdisone = 1;
break;
690 if ( tf[1] != firstvalue ) {
691 argsdone++; gcdisone = 1;
break;
693 if ( *t == -MINVECTOR ) { firstshort = -VECTOR; }
694 if ( firstshort == -MINVECTOR ) { firstshort = -VECTOR; }
696 else if ( *tf > -FUNCTION && *tf != -SNUMBER && tf[1] != firstvalue ) {
697 argsdone++; gcdisone = 1;
break;
699 if ( *tf == -SNUMBER && firstvalue != tf[1] ) {
703 if ( firstvalue == 1 || tf[1] == 1 ) { gcdisone = 1;
break; }
704 if ( firstvalue < 0 && tf[1] < 0 ) {
705 x1 = -firstvalue; x2 = -tf[1]; sign = -1;
708 x1 = ABS(firstvalue); x2 = ABS(tf[1]); sign = 1;
710 while ( ( x3 = x1%x2 ) != 0 ) { x1 = x2; x2 = x3; }
711 firstvalue = ((WORD)x2)*sign;
713 if ( firstvalue == 1 ) { gcdisone = 1;
break; }
717 termout = AT.WorkPointer;
718 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
719 if ( AT.WorkPointer > AT.WorkTop ) {
720 MLOCK(ErrorMessageLock);
722 MUNLOCK(ErrorMessageLock);
731 i = t - term; tin = term; tout = termout;
733 if ( gcdisone || ( firstshort == -SNUMBER && firstvalue == 1 ) ) {
736 tin += t[1]; tstop = term + *term;
737 while ( tin < tstop ) *tout++ = *tin++;
738 *termout = tout - termout;
739 if ( sign < 0 ) tout[-1] = -tout[-1];
740 AT.WorkPointer = tout;
741 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
742 AT.WorkPointer = termout;
743 AT.pWorkPointer = args;
750 if ( numargs == 0 ) {
753 if ( firstshort == 0 )
goto gcdone;
754 if ( firstshort == -SNUMBER ) {
755 *tout++ = SNUMBER; *tout++ = 4; *tout++ = firstvalue; *tout++ = 1;
758 else if ( firstshort == -SYMBOL ) {
759 *tout++ = SYMBOL; *tout++ = 4; *tout++ = firstvalue; *tout++ = 1;
762 else if ( firstshort == -VECTOR || firstshort == -INDEX ) {
763 *tout++ = INDEX; *tout++ = 3; *tout++ = firstvalue;
goto gcdone;
765 else if ( firstshort == -MINVECTOR ) {
767 *tout++ = INDEX; *tout++ = 3; *tout++ = firstvalue;
goto gcdone;
769 else if ( firstshort <= -FUNCTION ) {
770 *tout++ = firstvalue; *tout++ = FUNHEAD; FILLFUN(tout);
775 MLOCK(ErrorMessageLock);
776 MesPrint(
"!>Internal error. Illegal short argument in GCDfunction.");
777 MUNLOCK(ErrorMessageLock);
790 switch ( firstshort ) {
792 sh[0] = 4; sh[1] = ABS(firstvalue); sh[2] = 1;
793 if ( firstvalue < 0 ) sh[3] = -3;
800 sh[0] = 8; sh[1] = INDEX; sh[2] = 3; sh[3] = firstvalue;
801 sh[4] = 1; sh[5] = 1;
802 if ( firstshort == -MINVECTOR ) sh[6] = -3;
807 sh[0] = 8; sh[1] = SYMBOL; sh[2] = 4; sh[3] = firstvalue; sh[4] = 1;
808 sh[5] = 1; sh[6] = 1; sh[7] = 3; sh[8] = 0;
811 sh[0] = FUNHEAD+4; sh[1] = firstshort; sh[2] = FUNHEAD;
812 for ( i = 2; i < FUNHEAD; i++ ) sh[i+1] = 0;
813 sh[FUNHEAD+1] = 1; sh[FUNHEAD+2] = 1; sh[FUNHEAD+3] = 3; sh[FUNHEAD+4] = 0;
824 for ( i = 1; i < numargs; i++ ) {
825 for ( ii = i; ii > 0; ii-- ) {
826 arg1 = AT.pWorkSpace[args+ii];
827 arg2 = AT.pWorkSpace[args+ii-1];
830 if ( *arg1 == -EXPRESSION )
break;
831 if ( *arg2 == -DOLLAREXPRESSION )
break;
832 AT.pWorkSpace[args+ii] = arg2;
833 AT.pWorkSpace[args+ii-1] = arg1;
837 else if ( *arg2 < 0 ) {
838 AT.pWorkSpace[args+ii] = arg2;
839 AT.pWorkSpace[args+ii-1] = arg1;
842 if ( *arg1 > *arg2 ) {
843 AT.pWorkSpace[args+ii] = arg2;
844 AT.pWorkSpace[args+ii-1] = arg1;
857 for ( i = istart; i < numargs; i++ ) {
858 arg1 = AT.pWorkSpace[args+i];
860 oldval1 = arg1[*arg1]; arg1[*arg1] = 0;
863 GCDterms(BHEAD mh,m,mh); m += *m;
864 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
865 gcdisone = 1; sign = 1; arg1[*arg1] = oldval1;
goto gcdone;
868 arg1[*arg1] = oldval1;
870 else if ( *arg1 == -DOLLAREXPRESSION ) {
871 if ( ( d = DolToTerms(BHEAD arg1[1]) ) != 0 ) {
874 GCDterms(BHEAD mh,m,mh); m += *m;
876 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
877 gcdisone = 1; sign = 1;
878 if ( d->factors ) M_free(d->factors,
"Dollar factors");
879 M_free(d,
"Copy of dollar variable");
goto gcdone;
882 if ( d->factors ) M_free(d->factors,
"Dollar factors");
883 M_free(d,
"Copy of dollar variable");
887 mm = CreateExpression(BHEAD arg1[1]);
890 GCDterms(BHEAD mh,m,mh); m += *m;
892 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
893 gcdisone = 1; sign = 1; M_free(mm,
"CreateExpression");
goto gcdone;
896 M_free(mm,
"CreateExpression");
901 firstshort = -SNUMBER; firstvalue = mh[1] * (mh[3]/3);
903 else if ( mh[1] == SYMBOL ) {
904 firstshort = -SYMBOL; firstvalue = mh[3];
906 else if ( mh[1] == INDEX ) {
907 firstshort = -INDEX; firstvalue = mh[3];
908 if ( mh[6] == -3 ) firstshort = -MINVECTOR;
910 else if ( mh[1] >= FUNCTION ) {
911 firstshort = -mh[1]; firstvalue = mh[1];
932 for ( i = 0; i < numargs; i++ ) {
933 arg1 = AT.pWorkSpace[args+i];
934 if ( *arg1 > 0 && arg1[ARGHEAD]+ARGHEAD == *arg1 ) {
939 arg2 = AT.pWorkSpace[args];
940 AT.pWorkSpace[args] = arg1;
941 AT.pWorkSpace[args+1] = arg2;
943 m = mh = AT.WorkPointer;
944 mm = arg1+ARGHEAD; i = *mm;
965 for ( i = 0; i < numargs; i++ ) {
966 arg1 = AT.pWorkSpace[args+i];
968 m = (WORD *)Malloc1(*arg1*
sizeof(WORD),
"argbuffer type 0");
978 else if ( *arg1 == -DOLLAREXPRESSION ) {
979 d = DolToTerms(BHEAD arg1[1]);
980 abuf[i].buffer = d->where;
984 if ( *m ) argsdone++;
986 abuf[i].size = m-abuf[i].buffer;
988 else if ( *arg1 == -EXPRESSION ) {
989 abuf[i].buffer = CreateExpression(BHEAD arg1[1]);
992 if ( *m ) argsdone++;
994 abuf[i].size = m-abuf[i].buffer;
998 MLOCK(ErrorMessageLock);
999 MesPrint(
"!>What argument is this?");
1000 MUNLOCK(ErrorMessageLock);
1005 for ( i = 0; i < numargs; i++ ) {
1006 arg1 = abuf[i].buffer;
1007 if ( *arg1 == 0 ) {}
1008 else if ( arg1[*arg1] == 0 ) {
1012 ab = abuf[i]; abuf[i] = abuf[0]; abuf[0] = ab;
1013 mh = abuf[0].buffer;
1014 for ( j = 1; j < numargs; j++ ) {
1017 GCDterms(BHEAD mh,m,mh); m += *m;
1019 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
1020 gcdisone = 1; sign = 1;
break;
1025 mm = mh + *mh;
if ( mm[-1] < 0 ) { sign = -1; mm[-1] = -mm[-1]; }
1026 mstop = mm - mm[-1]; m = mh+1; mlength = mm[-1];
1027 while ( tin < t ) *tout++ = *tin++;
1028 while ( m < mstop ) *tout++ = *m++;
1030 while ( tin < tstop ) *tout++ = *tin++;
1031 tlength = REDLENG(tlength);
1032 mlength = REDLENG(mlength);
1033 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)mstop,mlength,
1034 (UWORD *)tout,&newlength) < 0 )
goto CalledFrom;
1035 mlength = INCLENG(newlength);
1036 tout += ABS(mlength);
1037 tout[-1] = mlength*sign;
1038 *termout = tout - termout;
1039 AT.WorkPointer = tout;
1040 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
1048 for ( i = 1; i < numargs; i++ ) {
1049 for ( ii = i; ii > 0; ii-- ) {
1050 if ( abuf[ii-1].size <= abuf[ii].size )
break;
1051 ab = abuf[ii-1]; abuf[ii-1] = abuf[ii]; abuf[ii] = ab;
1059 gcdout = abuf[ii].buffer;
1060 for ( i = 0; i < numargs; i++ ) {
1061 if ( abuf[i].buffer[0] ) { gcdout = abuf[i].buffer; ii = i; i++; argsdone++;
break; }
1063 for ( ; i < numargs; i++ ) {
1064 if ( abuf[i].buffer[0] ) {
1065 g = GCDfunction3(BHEAD gcdout,abuf[i].buffer);
1067 if ( gcdout != abuf[ii].buffer ) M_free(gcdout,
"gcdout");
1069 if ( gcdout[*gcdout] == 0 && gcdout[0] == 4 && gcdout[1] == 1
1070 && gcdout[2] == 1 && gcdout[3] == 3 )
break;
1075 tlength = REDLENG(tlength);
1077 tin = term; tout = termout;
while ( tin < t ) *tout++ = *tin++;
1079 mnext = mm + *mm; mlength = mnext[-1]; mstop = mnext - ABS(mlength);
1081 while ( mm < mstop ) *tout++ = *mm++;
1082 while ( tin < tstop ) *tout++ = *tin++;
1083 mlength = REDLENG(mlength);
1084 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)mm,mlength,
1085 (UWORD *)tout,&newlength) < 0 )
goto CalledFrom;
1086 mlength = INCLENG(newlength);
1087 tout += ABS(mlength);
1089 *termout = tout - termout;
1090 AT.WorkPointer = tout;
1091 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
1094 if ( action && ( gcdout != abuf[ii].buffer ) ) M_free(gcdout,
"gcdout");
1101 for ( i = 0; i < numargs; i++ ) {
1102 if ( abuf[i].type == 0 ) { M_free(abuf[i].buffer,
"argbuffer type 0"); }
1103 else if ( abuf[i].type == 1 ) {
1105 if ( d->factors ) M_free(d->factors,
"Dollar factors");
1106 M_free(d,
"Copy of dollar variable");
1108 else if ( abuf[i].type == 2 ) { M_free(abuf[i].buffer,
"CreateExpression"); }
1110 M_free(abuf,
"argbuffer");
1115 AT.pWorkPointer = args;
1116 AT.WorkPointer = termout;
1120 MLOCK(ErrorMessageLock);
1121 MesCall(
"GCDfunction");
1122 MUNLOCK(ErrorMessageLock);
1147WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2)
1150 WORD oldsorttype = AR.SortType, *ow = AT.WorkPointer;;
1151 WORD *t, *tt, *gcdout, *term1, *term2, *confree1, *confree2, *gcdout1, *proper1, *proper2;
1152 int i, actionflag1, actionflag2;
1153 WORD startebuf = cbuf[AT.ebufnum].numrhs;
1154 WORD tryterm1, tryterm2;
1155 if ( in2[*in2] == 0 ) { t = in1; in1 = in2; in2 = t; }
1156 if ( in1[*in1] == 0 ) {
1157 gcdout = (WORD *)Malloc1((*in1+1)*
sizeof(WORD),
"gcdout");
1158 i = *in1; t = gcdout; tt = in1; NCOPY(t,tt,i); *t = 0;
1161 GCDterms(BHEAD gcdout,t,gcdout);
1162 if ( gcdout[0] == 4 && gcdout[1] == 1
1163 && gcdout[2] == 1 && gcdout[3] == 3 )
break;
1166 AT.WorkPointer = ow;
1173 AR.SortType = SORTHIGHFIRST;
1174 term1 = TermMalloc(
"GCDfunction3-a");
1175 term2 = TermMalloc(
"GCDfunction3-b");
1177 tryterm1 = AN.tryterm; AN.tryterm = 0;
1179 tryterm2 = AN.tryterm; AN.tryterm = 0;
1184 GCDterms(BHEAD term1,term2,term1);
1185 TermFree(term2,
"GCDfunction3-b");
1190 if ( ( proper1 = PutExtraSymbols(BHEAD confree1,startebuf,&actionflag1) ) == 0 )
goto CalledFrom;
1191 if ( confree1 != in1 ) {
1192 if ( tryterm1 ) { TermFree(confree1,
"TakeContent"); }
1193 else { M_free(confree1,
"TakeContent"); }
1198 if ( ( proper2 = PutExtraSymbols(BHEAD confree2,startebuf,&actionflag2) ) == 0 )
goto CalledFrom;
1199 if ( confree2 != in2 ) {
1200 if ( tryterm2 ) { TermFree(confree2,
"TakeContent"); }
1201 else { M_free(confree2,
"TakeContent"); }
1209 gcdout1 =
poly_gcd(BHEAD proper1,proper2,0);
1210 M_free(proper1,
"PutExtraSymbols");
1211 M_free(proper2,
"PutExtraSymbols");
1213 AR.SortType = oldsorttype;
1214 if ( actionflag1 || actionflag2 ) {
1215 if ( ( gcdout = TakeExtraSymbols(BHEAD gcdout1,startebuf) ) == 0 )
goto CalledFrom;
1216 M_free(gcdout1,
"gcdout");
1222 cbuf[AT.ebufnum].numrhs = startebuf;
1226 if ( term1[0] != 4 || term1[3] != 3 || term1[1] != 1 || term1[2] != 1 ) {
1228 if ( ( gcdout1 = MultiplyWithTerm(BHEAD gcdout,term1,2) ) == 0 )
goto CalledFrom;
1230 M_free(gcdout,
"gcdout");
1233 TermFree(term1,
"GCDfunction3-a");
1234 AT.WorkPointer = ow;
1238 MLOCK(ErrorMessageLock);
1239 MesCall(
"GCDfunction3");
1240 MUNLOCK(ErrorMessageLock);
1249WORD *PutExtraSymbols(PHEAD WORD *in,WORD startebuf,
int *actionflag)
1251 WORD *termout = AT.WorkPointer;
1260 if ( action > 0 ) *actionflag = 1;
1264 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1267 MLOCK(ErrorMessageLock);
1268 MesCall(
"PutExtraSymbols");
1269 MUNLOCK(ErrorMessageLock);
1278WORD *TakeExtraSymbols(PHEAD WORD *in,WORD startebuf)
1280 CBUF *C = cbuf+AC.cbufnum;
1281 CBUF *CC = cbuf+AT.ebufnum;
1282 WORD *oldworkpointer = AT.WorkPointer, *termout;
1284 termout = AT.WorkPointer;
1287 if ( ConvertFromPoly(BHEAD in,termout,numxsymbol,CC->numrhs-startebuf+numxsymbol,startebuf-numxsymbol,1) <= 0 ) {
1292 AT.WorkPointer = termout + *termout;
1296 if (
Generator(BHEAD termout,C->numlhs) ) {
1301 AT.WorkPointer = oldworkpointer;
1302 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1306 MLOCK(ErrorMessageLock);
1307 MesCall(
"TakeExtraSymbols");
1308 MUNLOCK(ErrorMessageLock);
1317WORD *MultiplyWithTerm(PHEAD WORD *in, WORD *term, WORD par)
1319 WORD *termout, *t, *tt, *tstop, *ttstop;
1320 WORD length, length1, length2;
1321 WORD oldsorttype = AR.SortType;
1322 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
1325 if ( par == 0 || par == 2 ) AR.SortType = SORTHIGHFIRST;
1326 else AR.SortType = SORTLOWFIRST;
1327 termout = AT.WorkPointer;
1331 tstop = in + *in; tstop -= ABS(tstop[-1]); t = in + 1;
1332 while ( t < tstop ) *tt++ = *t++;
1333 ttstop = term + *term; ttstop -= ABS(ttstop[-1]); t = term + 1;
1334 while ( t < ttstop ) *tt++ = *t++;
1335 length1 = REDLENG(in[*in-1]); length2 = REDLENG(term[*term-1]);
1336 if ( MulRat(BHEAD (UWORD *)tstop,length1,
1337 (UWORD *)ttstop,length2,(UWORD *)tt,&length) )
goto CalledFrom;
1338 length = INCLENG(length);
1339 tt += ABS(length); tt[-1] = length;
1340 *termout = tt - termout;
1342 Normalize(BHEAD termout);
1349 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1352 if (
EndSort(BHEAD termout,1) < 0 )
goto CalledFrom;
1355 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
1357 AR.SortType = oldsorttype;
1361 MLOCK(ErrorMessageLock);
1362 MesCall(
"MultiplyWithTerm");
1363 MUNLOCK(ErrorMessageLock);
1385 WORD *t, *tstop, *tcom, *tout, *tstore, *r, *rstop, *m, *mm, *w, *ww, *wterm;
1386 WORD *tnext, *tt, *tterm, code[2];
1388 int i, j, k, action = 0, sign;
1389 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMbuffer2, *ap;
1390 WORD GCDlen, GCDlen2, LCMlen, LCMlen2, length, redlength, len1, len2;
1391 tout = tstore = term+1;
1397 tstop = tnext-ABS(tnext[-1]);
1399 while ( t < tstop ) {
1400 if ( *t == INDEX ) {
1401 i = t[1]; NCOPY(tout,t,i);
break;
1405 if ( tout > tstore ) {
1409 rstop = tnext - ABS(tnext[-1]);
1411 if ( r == rstop )
goto noindices;
1412 while ( r < rstop ) {
1413 if ( *r != INDEX ) { r += r[1];
continue; }
1415 while ( m < tout ) {
1416 for ( i = 2; i < r[1]; i++ ) {
1417 if ( *m == r[i] )
break;
1421 while ( mm < tout ) { mm[-1] = mm[0]; mm++; }
1422 tout--; tstore[1]--; m--;
1428 if ( tout <= tstore+2 ) {
1429 tout = tstore;
break;
1433 if ( tout > tstore+2 ) {
1437 tnext = t + *t; t++; w++;
1438 while ( *t != INDEX ) { i = t[1]; NCOPY(w,t,i); }
1439 tt = t + t[1]; t += 2; r = tstore+2; ww = w; *w++ = INDEX; w++;
1440 while ( r < tout && t < tt ) {
1441 if ( *r > *t ) { *w++ = *t++; }
1442 else if ( *r == *t ) { r++; t++; }
1443 else goto CalledFrom;
1445 if ( r < tout )
goto CalledFrom;
1446 while ( t < tt ) *w++ = *t++;
1448 if ( ww[1] == 2 ) w = ww;
1449 while ( t < tnext ) *w++ = *t++;
1461 code[0] = VECTOR; code[1] = DELTA;
1462 for ( k = 0; k < 2; k++ ) {
1465 tstop = tnext-ABS(tnext[-1]);
1467 while ( t < tstop ) {
1468 if ( *t == code[k] ) {
1469 i = t[1]; NCOPY(tout,t,i);
break;
1473 if ( tout > tstore ) {
1477 rstop = tnext - ABS(tnext[-1]);
1479 if ( r == rstop ) { tstore = tout;
goto novectors; }
1480 while ( r < rstop ) {
1481 if ( *r != code[k] ) { r += r[1];
continue; }
1483 while ( m < tout ) {
1484 for ( i = 2; i < r[1]; i += 2 ) {
1485 if ( *m == r[i] && m[1] == r[i+1] )
break;
1489 while ( mm < tout ) { mm[-2] = mm[0]; mm[-1] = mm[1]; mm += 2; }
1490 tout -= 2; tstore[1] -= 2; m -= 2;
1496 if ( tout <= tstore+2 ) {
1497 tout = tstore;
break;
1501 if ( tout > tstore+2 ) {
1505 tnext = t + *t; t++; w++;
1506 while ( *t != code[k] ) { i = t[1]; NCOPY(w,t,i); }
1507 tt = t + t[1]; t += 2; r = tstore+2; ww = w; *w++ = code[k]; w++;
1508 while ( r < tout && t < tt ) {
1509 if ( ( *r > *t ) || ( *r == *t && r[1] > t[1] ) )
1510 { *w++ = *t++; *w++ = *t++; }
1511 else if ( *r == *t && r[1] == t[1] ) { r += 2; t += 2; }
1512 else goto CalledFrom;
1514 if ( r < tout )
goto CalledFrom;
1515 while ( t < tt ) *w++ = *t++;
1517 if ( ww[1] == 2 ) w = ww;
1518 while ( t < tnext ) *w++ = *t++;
1533 tstop = tnext-ABS(tnext[-1]);
1536 while ( t < tstop ) {
1537 if ( *t >= FUNCTION ) {
1538 if ( functions[*t-FUNCTION].commute ) {
1539 if ( tcom == 0 ) { tcom = tout; }
1541 for ( i = 0; i < t[1]; i++ ) {
1542 if ( t[i] != tcom[i] ) {
1543 MLOCK(ErrorMessageLock);
1544 MesPrint(
"GCD or factorization of more than one noncommuting object not allowed");
1545 MUNLOCK(ErrorMessageLock);
1551 i = t[1]; NCOPY(tout,t,i);
1555 if ( tout > tstore ) {
1558 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1559 if ( t == tstop )
goto nofunctions;
1561 while ( r < tout ) {
1563 while ( tt < tstop ) {
1564 for ( i = 0; i < r[1]; i++ ) {
1565 if ( r[i] != tt[i] )
break;
1567 if ( i == r[1] ) { r += r[1];
goto nextr1; }
1573 m = r; mm = r + r[1];
1574 while ( mm < tout ) *m++ = *mm++;
1578 if ( tout <= tstore )
break;
1582 if ( tout > tstore ) {
1588 while ( r < tout ) {
1589 t = in; ww = w = in;
1596 for ( i = 0; i < r[1]; i++ ) {
1597 if ( t[i] != r[i] ) {
1598 j = t[1]; NCOPY(w,t,j);
1604 while ( t < tnext ) *w++ = *t++;
1625 tterm = AT.WorkPointer; tt = tterm+1;
1626 tout[0] = SYMBOL; tout[1] = 2;
1628 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1629 while ( t < tstop ) {
1630 if ( *t == SYMBOL ) {
1631 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
1638 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1644 while ( t < tstop ) {
1645 if ( *t == SYMBOL ) {
1646 MergeSymbolLists(BHEAD tout,t,-1);
1654 if ( tout[1] > 2 ) {
1656 tt[0] = t[0]; tt[1] = t[1];
1657 for ( i = 2; i < t[1]; i += 2 ) {
1658 tt[i] = t[i]; tt[i+1] = -t[i+1];
1673 tout[0] = DOTPRODUCT; tout[1] = 2;
1675 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1676 while ( t < tstop ) {
1677 if ( *t == DOTPRODUCT ) {
1678 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
1685 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1690 while ( t < tstop ) {
1691 if ( *t == DOTPRODUCT ) {
1692 MergeDotproductLists(BHEAD tout,t,-1);
1699 if ( tout[1] > 2 ) {
1701 tt[0] = t[0]; tt[1] = t[1];
1702 for ( i = 2; i < t[1]; i += 3 ) {
1703 tt[i] = t[i]; tt[i+1] = t[i+1]; tt[i+2] = -t[i+2];
1716 AT.WorkPointer = tt;
1717 if ( AN.cmod != 0 ) {
1719 t = in; tnext = t + *t; tstop = tnext - ABS(tnext[-1]);
1721 if ( tnext[-1] < 0 ) x += AC.cmod[0];
1722 if (
GetModInverses(x,(WORD)(AN.cmod[0]),&ix,&ip) )
goto CalledFrom;
1723 *tout++ = x; *tout++ = 1; *tout++ = 3;
1724 *tt++ = ix; *tt++ = 1; *tt++ = 3;
1727 GCDbuffer = NumberMalloc(
"MakeInteger");
1728 GCDbuffer2 = NumberMalloc(
"MakeInteger");
1729 LCMbuffer = NumberMalloc(
"MakeInteger");
1730 LCMbuffer2 = NumberMalloc(
"MakeInteger");
1732 tnext = t + *t; length = tnext[-1];
1733 if ( length < 0 ) { sign = -1; length = -length; }
1735 tstop = tnext - length;
1736 redlength = (length-1)/2;
1737 for ( i = 0; i < redlength; i++ ) {
1738 GCDbuffer[i] = (UWORD)(tstop[i]);
1739 LCMbuffer[i] = (UWORD)(tstop[redlength+i]);
1741 GCDlen = LCMlen = redlength;
1742 while ( GCDbuffer[GCDlen-1] == 0 ) GCDlen--;
1743 while ( LCMbuffer[LCMlen-1] == 0 ) LCMlen--;
1746 tnext = t + *t; length = ABS(tnext[-1]);
1747 tstop = tnext - length; redlength = (length-1)/2;
1748 len1 = len2 = redlength;
1749 den = tstop + redlength;
1750 while ( tstop[len1-1] == 0 ) len1--;
1751 while ( den[len2-1] == 0 ) len2--;
1752 if ( GCDlen == 1 && GCDbuffer[0] == 1 ) {}
1754 GcdLong(BHEAD (UWORD *)tstop,len1,GCDbuffer,GCDlen,GCDbuffer2,&GCDlen2);
1755 ap = GCDbuffer; GCDbuffer = GCDbuffer2; GCDbuffer2 = ap;
1756 a = GCDlen; GCDlen = GCDlen2; GCDlen2 = a;
1758 if ( len2 == 1 && den[0] == 1 ) {}
1760 GcdLong(BHEAD LCMbuffer,LCMlen,(UWORD *)den,len2,LCMbuffer2,&LCMlen2);
1761 DivLong((UWORD *)den,len2,LCMbuffer2,LCMlen2,
1762 GCDbuffer2,&GCDlen2,(UWORD *)AT.WorkPointer,&a);
1763 MulLong(LCMbuffer,LCMlen,GCDbuffer2,GCDlen2,LCMbuffer2,&LCMlen2);
1764 ap = LCMbuffer; LCMbuffer = LCMbuffer2; LCMbuffer2 = ap;
1765 a = LCMlen; LCMlen = LCMlen2; LCMlen2 = a;
1769 if ( GCDlen != 1 || GCDbuffer[0] != 1 || LCMlen != 1 || LCMbuffer[0] != 1 ) {
1770 redlength = GCDlen;
if ( LCMlen > GCDlen ) redlength = LCMlen;
1771 for ( i = 0; i < GCDlen; i++ ) *tout++ = (WORD)(GCDbuffer[i]);
1772 for ( ; i < redlength; i++ ) *tout++ = 0;
1773 for ( i = 0; i < LCMlen; i++ ) *tout++ = (WORD)(LCMbuffer[i]);
1774 for ( ; i < redlength; i++ ) *tout++ = 0;
1775 *tout++ = (2*redlength+1)*sign;
1776 for ( i = 0; i < LCMlen; i++ ) *tt++ = (WORD)(LCMbuffer[i]);
1777 for ( ; i < redlength; i++ ) *tt++ = 0;
1778 for ( i = 0; i < GCDlen; i++ ) *tt++ = (WORD)(GCDbuffer[i]);
1779 for ( ; i < redlength; i++ ) *tt++ = 0;
1780 *tt++ = (2*redlength+1)*sign;
1784 *tout++ = 1; *tout++ = 1; *tout++ = 3*sign;
1785 *tt++ = 1; *tt++ = 1; *tt++ = 3*sign;
1786 if ( sign != 1 ) action++;
1789 NumberFree(LCMbuffer2,
"MakeInteger");
1790 NumberFree(LCMbuffer ,
"MakeInteger");
1791 NumberFree(GCDbuffer2,
"MakeInteger");
1792 NumberFree(GCDbuffer ,
"MakeInteger");
1799 *tterm = tt - tterm;
1800 AT.WorkPointer = tt;
1801 inp = MultiplyWithTerm(BHEAD in,tterm,2);
1802 AT.WorkPointer = tterm;
1808 *term = tout - term;
1809 AT.WorkPointer = tterm;
1812 MLOCK(ErrorMessageLock);
1813 MesCall(
"TakeContent");
1814 MUNLOCK(ErrorMessageLock);
1830int MergeSymbolLists(PHEAD WORD *old, WORD *extra,
int par)
1833 WORD *
new = TermMalloc(
"MergeSymbolLists");
1834 WORD *t1, *t2, *fill;
1837 i1 = old[1] - 2; i2 = extra[1] - 2;
1838 t1 = old + 2; t2 = extra + 2;
1841 while ( i1 > 0 && i2 > 0 ) {
1843 if ( t2[1] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1847 else if ( *t1 < *t2 ) {
1848 if ( t1[1] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1852 else if ( t1[1] < t2[1] ) {
1853 *fill++ = *t1++; *fill++ = *t1++; t2 += 2;
1857 *fill++ = *t2++; *fill++ = *t2++; t1 += 2;
1861 for ( ; i1 > 0; i1 -= 2 ) {
1862 if ( t1[1] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1865 for ( ; i2 > 0; i2 -= 2 ) {
1866 if ( t2[1] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1871 while ( i1 > 0 && i2 > 0 ) {
1873 if ( t2[1] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1877 else if ( *t1 < *t2 ) {
1878 if ( t1[1] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1882 else if ( t1[1] > t2[1] ) {
1883 *fill++ = *t1++; *fill++ = *t1++; t2 += 2;
1887 *fill++ = *t2++; *fill++ = *t2++; t1 += 2;
1891 for ( ; i1 > 0; i1 -= 2 ) {
1892 if ( t1[1] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1895 for ( ; i2 > 0; i2 -= 2 ) {
1896 if ( t2[1] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1901 while ( i1 > 0 && i2 > 0 ) {
1905 else if ( *t1 < *t2 ) {
1908 else if ( ( t1[1] > 0 ) && ( t2[1] < 0 ) ) { t1 += 2; t2 += 2; i1 -= 2; i2 -= 2; }
1909 else if ( ( t1[1] < 0 ) && ( t2[1] > 0 ) ) { t1 += 2; t2 += 2; i1 -= 2; i2 -= 2; }
1910 else if ( t1[1] > 0 ) {
1911 if ( t1[1] < t2[1] ) {
1912 *fill++ = *t1++; *fill++ = *t1++; t2 += 2; i2 -= 2;
1915 *fill++ = *t2++; *fill++ = *t2++; t1 += 2; i1 -= 2;
1919 if ( t2[1] < t1[1] ) {
1920 *fill++ = *t2++; *fill++ = *t2++; t1 += 2; i1 -= 2; i2 -= 2;
1923 *fill++ = *t1++; *fill++ = *t1++; t2 += 2; i1 -= 2; i2 -= 2;
1927 for ( ; i1 > 0; i1-- ) *fill++ = *t1++;
1928 for ( ; i2 > 0; i2-- ) *fill++ = *t2++;
1932 i1 =
new[1] = fill -
new;
1933 t2 =
new; t1 = old; NCOPY(t1,t2,i1);
1934 TermFree(
new,
"MergeSymbolLists");
1950int MergeDotproductLists(PHEAD WORD *old, WORD *extra,
int par)
1953 WORD *
new = TermMalloc(
"MergeDotproductLists");
1954 WORD *t1, *t2, *fill;
1957 i1 = old[1] - 2; i2 = extra[1] - 2;
1958 t1 = old + 2; t2 = extra + 2;
1961 while ( i1 > 0 && i2 > 0 ) {
1962 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
1963 if ( t2[2] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1967 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
1968 if ( t1[2] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
1972 else if ( t1[2] < t2[2] ) {
1973 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
1977 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
1981 for ( ; i1 > 0; i1 -= 3 ) {
1982 if ( t1[2] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
1985 for ( ; i2 > 0; i2 -= 3 ) {
1986 if ( t2[2] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1991 while ( i1 > 0 && i2 > 0 ) {
1992 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
1993 if ( t2[2] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1997 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
1998 if ( t1[2] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
2002 else if ( t1[2] > t2[2] ) {
2003 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2007 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2011 for ( ; i1 > 0; i1 -= 3 ) {
2012 if ( t1[2] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
2015 for ( ; i2 > 0; i2 -= 3 ) {
2016 if ( t2[2] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
2021 while ( i1 > 0 && i2 > 0 ) {
2022 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
2026 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
2030 else if ( ( t1[2] > 0 ) && ( t2[2] < 0 ) ) { t1 += 3; t2 += 3; i1 -= 3; i2 -= 3; }
2031 else if ( ( t1[2] < 0 ) && ( t2[2] > 0 ) ) { t1 += 3; t2 += 3; i1 -= 3; i2 -= 3; }
2032 else if ( t1[2] > 0 ) {
2033 if ( t1[2] < t2[2] ) {
2034 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2038 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2044 if ( t2[2] < t1[2] ) {
2045 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2049 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2054 for ( ; i1 > 0; i1-- ) *fill++ = *t1++;
2055 for ( ; i2 > 0; i2-- ) *fill++ = *t2++;
2058 new[0] = DOTPRODUCT;
2059 i1 =
new[1] = fill -
new;
2060 t2 =
new; t1 = old; NCOPY(t1,t2,i1);
2061 TermFree(
new,
"MergeDotproductLists");
2077WORD *CreateExpression(PHEAD WORD nexp)
2080 CBUF *C = cbuf+AC.cbufnum;
2081 POSITION startposition, oldposition;
2083 WORD *term, *oldipointer = AR.CompressPointer;
2085 switch ( Expressions[nexp].status ) {
2086 case HIDDENLEXPRESSION:
2087 case HIDDENGEXPRESSION:
2088 case DROPHLEXPRESSION:
2089 case DROPHGEXPRESSION:
2090 case UNHIDELEXPRESSION:
2091 case UNHIDEGEXPRESSION:
2092 AR.GetOneFile = 2; fi = AR.hidefile;
2095 AR.GetOneFile = 0; fi = AR.infile;
2098 SeekScratch(fi,&oldposition);
2099 startposition = AS.OldOnFile[nexp];
2100 term = AT.WorkPointer;
2101 if ( GetOneTerm(BHEAD term,fi,&startposition,0) <= 0 )
goto CalledFrom;
2103 AR.CompressPointer = oldipointer;
2104 while ( GetOneTerm(BHEAD term,fi,&startposition,0) > 0 ) {
2105 AT.WorkPointer = term + *term;
2106 if (
Generator(BHEAD term,C->numlhs) ) {
2110 AR.CompressPointer = oldipointer;
2112 AT.WorkPointer = term;
2113 if (
EndSort(BHEAD (WORD *)((
void *)(&term)),2) < 0 )
goto CalledFrom;
2114 SetScratch(fi,&oldposition);
2117 MLOCK(ErrorMessageLock);
2118 MesCall(
"CreateExpression");
2119 MUNLOCK(ErrorMessageLock);
2133int GCDterms(PHEAD WORD *term1, WORD *term2, WORD *termout)
2136 WORD *t1, *t1stop, *t1next, *t2, *t2stop, *t2next, *tout, *tt1, *tt2;
2137 int count1, count2, i, ii, x1, sign;
2138 WORD length1, length2;
2139 t1 = term1 + *term1; t1stop = t1 - ABS(t1[-1]); t1 = term1+1;
2140 t2 = term2 + *term2; t2stop = t2 - ABS(t2[-1]); t2 = term2+1;
2142 while ( t1 < t1stop ) {
2143 t1next = t1 + t1[1];
2145 if ( *t1 == SYMBOL ) {
2146 while ( t2 < t2stop && *t2 != SYMBOL ) t2 += t2[1];
2147 if ( t2 < t2stop && *t2 == SYMBOL ) {
2149 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2150 while ( tt1 < t1next && tt2 < t2next ) {
2151 if ( *tt1 < *tt2 ) tt1 += 2;
2152 else if ( *tt1 > *tt2 ) tt2 += 2;
2153 else if ( ( tt1[1] > 0 && tt2[1] < 0 ) ||
2154 ( tt2[1] > 0 && tt1[1] < 0 ) ) {
2159 if ( tt1[1] < 0 ) {
if ( tt2[1] > x1 ) x1 = tt2[1]; }
2160 else {
if ( tt2[1] < x1 ) x1 = tt2[1]; }
2161 tout[count1+2] = *tt1;
2162 tout[count1+3] = x1;
2168 *tout = SYMBOL; tout[1] = count1+2; tout += tout[1];
2172 else if ( *t1 == DOTPRODUCT ) {
2173 while ( t2 < t2stop && *t2 != DOTPRODUCT ) t2 += t2[1];
2174 if ( t2 < t2stop && *t2 == DOTPRODUCT ) {
2176 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2177 while ( tt1 < t1next && tt2 < t2next ) {
2178 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 3;
2179 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 3;
2180 else if ( ( tt1[2] > 0 && tt2[2] < 0 ) ||
2181 ( tt2[2] > 0 && tt1[2] < 0 ) ) {
2186 if ( tt1[2] < 0 ) {
if ( tt2[2] > x1 ) x1 = tt2[2]; }
2187 else {
if ( tt2[2] < x1 ) x1 = tt2[2]; }
2188 tout[count1+2] = *tt1;
2189 tout[count1+3] = tt1[1];
2190 tout[count1+4] = x1;
2196 *tout = DOTPRODUCT; tout[1] = count1+2; tout += tout[1];
2200 else if ( *t1 == VECTOR ) {
2201 while ( t2 < t2stop && *t2 != VECTOR ) t2 += t2[1];
2202 if ( t2 < t2stop && *t2 == VECTOR ) {
2204 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2205 while ( tt1 < t1next && tt2 < t2next ) {
2206 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 2;
2207 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 2;
2209 tout[count1+2] = *tt1;
2210 tout[count1+3] = tt1[1];
2216 *tout = VECTOR; tout[1] = count1+2; tout += tout[1];
2220 else if ( *t1 == INDEX ) {
2221 while ( t2 < t2stop && *t2 != INDEX ) t2 += t2[1];
2222 if ( t2 < t2stop && *t2 == INDEX ) {
2224 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2225 while ( tt1 < t1next && tt2 < t2next ) {
2226 if ( *tt1 < *tt2 ) tt1 += 1;
2227 else if ( *tt1 > *tt2 ) tt2 += 1;
2229 tout[count1+2] = *tt1;
2235 *tout = INDEX; tout[1] = count1+2; tout += tout[1];
2239 else if ( *t1 == DELTA ) {
2240 while ( t2 < t2stop && *t2 != DELTA ) t2 += t2[1];
2241 if ( t2 < t2stop && *t2 == DELTA ) {
2243 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2244 while ( tt1 < t1next && tt2 < t2next ) {
2245 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 2;
2246 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 2;
2248 tout[count1+2] = *tt1;
2249 tout[count1+3] = tt1[1];
2255 *tout = DELTA; tout[1] = count1+2; tout += tout[1];
2259 else if ( *t1 >= FUNCTION ) {
2265 while ( t1next < t1stop && *t1 == *t1next && t1[1] == t1next[1] ) {
2266 for ( i = 2; i < t1[1]; i++ ) {
2267 if ( t1[i] != t1next[i] )
break;
2269 if ( i < t1[1] )
break;
2271 t1next += t1next[1];
2274 while ( t2 < t2stop ) {
2275 if ( *t2 == *t1 && t2[1] == t1[1] ) {
2276 for ( i = 2; i < t1[1]; i++ ) {
2277 if ( t2[i] != t1[i] )
break;
2279 if ( i >= t1[1] ) count2++;
2283 if ( count1 < count2 ) count2 = count1;
2286 while ( count2 > 0 ) { tout += tout[1]; count2--; }
2300 length1 = term1[*term1-1]; ii = i = ABS(length1); t1 = t1stop;
2301 if ( t1 != tout ) { NCOPY(tout,t1,i); tout -= ii; }
2302 length2 = term2[*term2-1];
2303 if ( length1 < 0 && length2 < 0 ) sign = -1;
2304 if ( AccumGCD(BHEAD (UWORD *)tout,&length1,(UWORD *)t2stop,length2) ) {
2305 MLOCK(ErrorMessageLock);
2306 MesCall(
"GCDterms");
2307 MUNLOCK(ErrorMessageLock);
2310 if ( sign < 0 && length1 > 0 ) length1 = -length1;
2311 tout += ABS(length1); tout[-1] = length1;
2312 *termout = tout - termout; *tout = 0;
2321int ReadPolyRatFun(PHEAD WORD *term)
2323 WORD *oldworkpointer = AT.WorkPointer;
2325 WORD *t, *fun, *nextt, *num, *den, *t1, *t2, size, numsize, densize;
2326 WORD *term1, *term2, *confree1, *confree2, *gcd, *num1, *den1, move, *newnum, *newden;
2327 WORD *tstop, *m1, *m2;
2328 WORD oldsorttype = AR.SortType;
2329 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
2330 AR.SortType = SORTHIGHFIRST;
2333 tstop = term + *term; tstop -= ABS(tstop[-1]);
2334 if ( term + *term == AT.WorkPointer ) flag = 1;
2337 while ( t < tstop ) {
2338 if ( *t != AR.PolyFun ) { t += t[1];
continue; }
2339 if ( ( t[2] & MUSTCLEANPRF ) == 0 ) { t += t[1];
continue; }
2342 if ( fun[1] > FUNHEAD && fun[FUNHEAD] == -SNUMBER && fun[FUNHEAD+1] == 0 )
2343 { *term = 0;
break; }
2344 if ( FromPolyRatFun(BHEAD fun, &num, &den) > 0 ) { t = nextt;
continue; }
2345 if ( *num == ARGHEAD ) { *term = 0;
break; }
2352 term1 = TermMalloc(
"ReadPolyRatFun");
2353 term2 = TermMalloc(
"ReadPolyRatFun");
2356 GCDclean(BHEAD term1,term2);
2358 gcd =
poly_gcd(BHEAD confree1,confree2,1);
2359 newnum = PolyDiv(BHEAD confree1,gcd,
"ReadPolyRatFun");
2360 newden = PolyDiv(BHEAD confree2,gcd,
"ReadPolyRatFun");
2361 TermFree(confree2,
"ReadPolyRatFun");
2362 TermFree(confree1,
"ReadPolyRatFun");
2363 num1 = MULfunc(BHEAD term1,newnum);
2364 den1 = MULfunc(BHEAD term2,newden);
2365 TermFree(newnum,
"ReadPolyRatFun");
2366 TermFree(newden,
"ReadPolyRatFun");
2368 TermFree(gcd,
"poly_gcd");
2369 TermFree(term1,
"ReadPolyRatFun");
2370 TermFree(term2,
"ReadPolyRatFun");
2377 if ( num1[0] == 4 && num1[4] == 0 && num1[2] == 1 && num1[1] > 0 ) {
2378 numsize = 2; num1[0] = -SNUMBER;
2379 if ( num1[3] < 0 ) num1[1] = -num1[1];
2381 else if ( num1[0] == 8 && num1[8] == 0 && num1[7] == 3 && num1[6] == 1
2382 && num1[5] == 1 && num1[1] == SYMBOL && num1[4] == 1 ) {
2383 numsize = 2; num1[0] = -SYMBOL; num1[1] = num1[3];
2385 else { m1 = num1;
while ( *m1 ) m1 += *m1; numsize = (m1-num1)+ARGHEAD; }
2386 if ( den1[0] == 4 && den1[4] == 0 && den1[2] == 1 && den1[1] > 0 ) {
2387 densize = 2; den1[0] = -SNUMBER;
2388 if ( den1[3] < 0 ) den1[1] = -den1[1];
2390 else if ( den1[0] == 8 && den1[8] == 0 && den1[7] == 3 && den1[6] == 1
2391 && den1[5] == 1 && den1[1] == SYMBOL && den1[4] == 1 ) {
2392 densize = 2; den1[0] = -SYMBOL; den1[1] = den1[3];
2394 else { m2 = den1;
while ( *m2 ) m2 += *m2; densize = (m2-den1)+ARGHEAD; }
2395 size = FUNHEAD+numsize+densize;
2397 if ( size > fun[1] ) {
2398 move = size - fun[1];
2399 t1 = term+*term; t2 = t1+move;
2400 while ( t1 > nextt ) *--t2 = *--t1;
2401 tstop += move; nextt += move;
2404 else if ( size < fun[1] ) {
2406 t2 = fun+size; t1 = nextt;
2407 tstop -= move; nextt -= move;
2409 while ( t1 < t ) *t2++ = *t1++;
2413 fun[1] = size; fun[2] = 0;
2414 t2 = fun+FUNHEAD; t1 = num1;
2415 if ( *num1 < 0 ) { *t2++ = num1[0]; *t2++ = num1[1]; }
2416 else { *t2++ = numsize; *t2++ = 0; FILLARG(t2);
2417 i = numsize-ARGHEAD; NCOPY(t2,t1,i) }
2419 if ( *den1 < 0 ) { *t2++ = den1[0]; *t2++ = den1[1]; }
2420 else { *t2++ = densize; *t2++ = 0; FILLARG(t2);
2421 i = densize-ARGHEAD; NCOPY(t2,t1,i) }
2423 TermFree(num1,
"MULfunc");
2424 TermFree(den1,
"MULfunc");
2428 if ( flag ) AT.WorkPointer = term +*term;
2429 else AT.WorkPointer = oldworkpointer;
2430 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
2431 AR.SortType = oldsorttype;
2440int FromPolyRatFun(PHEAD WORD *fun, WORD **numout, WORD **denout)
2442 WORD *nextfun, *tt, *num, *den;
2444 nextfun = fun + fun[1];
2446 num = AT.WorkPointer;
2448 if ( *fun != -SNUMBER && *fun != -SYMBOL )
goto Improper;
2449 ToGeneral(fun,num,0);
2450 tt = num + *num; *tt++ = 0;
2453 else { i = *fun; tt = num; NCOPY(tt,fun,i); *tt++ = 0; }
2456 if ( *fun != -SNUMBER && *fun != -SYMBOL )
goto Improper;
2457 ToGeneral(fun,den,0);
2458 tt = den + *den; *tt++ = 0;
2461 else { i = *fun; tt = den; NCOPY(tt,fun,i); *tt++ = 0; }
2462 *numout = num; *denout = den;
2463 if ( fun != nextfun ) {
return(1); }
2464 AT.WorkPointer = tt;
2468 MLOCK(ErrorMessageLock);
2469 MesPrint(
"!>Improper use of PolyRatFun");
2470 MesCall(
"FromPolyRatFun");
2471 MUNLOCK(ErrorMessageLock);
2496 WORD *t, *tstop, *tout, *tstore;
2497 WORD *tnext, *tt, *tterm;
2498 WORD *inp, a, *den, *oldworkpointer = AT.WorkPointer;
2499 int i, action = 0, sign, first;
2500 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMbuffer2, *ap;
2501 WORD GCDlen, GCDlen2, LCMlen, LCMlen2, length, redlength, len1, len2;
2503 tout = tstore = term+1;
2512 tterm = AT.WorkPointer; tt = tterm+1;
2513 tout[0] = SYMBOL; tout[1] = 2;
2516 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
2517 while ( t < tstop ) {
2519 if ( *t == SYMBOL ) {
2520 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
2524 MLOCK(ErrorMessageLock);
2525 MesPrint ((
char*)
"ERROR: polynomials and polyratfuns must contain symbols only");
2526 MUNLOCK(ErrorMessageLock);
2530 else if ( *t == SYMBOL ) {
2531 MergeSymbolLists(BHEAD tout,t,-1);
2543 for ( i = 2; i < tout[1]; i += 2 ) {
2544 if ( tout[i+1] < 0 ) {
2545 if ( i == j ) { j += 2; }
2546 else { tout[j] = tout[i]; tout[j+1] = tout[i+1]; j += 2; }
2555 if ( tout[1] > 2 ) {
2557 tt[0] = t[0]; tt[1] = t[1];
2558 for ( i = 2; i < t[1]; i += 2 ) {
2559 tt[i] = t[i]; tt[i+1] = -t[i+1];
2572 AT.WorkPointer = tt;
2573 if ( AN.cmod != 0 ) {
2575 t = in; tnext = t + *t; tstop = tnext - ABS(tnext[-1]);
2577 if ( tnext[-1] < 0 ) x += AC.cmod[0];
2578 if (
GetModInverses(x,(WORD)(AN.cmod[0]),&ix,&ip) )
goto CalledFrom;
2579 *tout++ = x; *tout++ = 1; *tout++ = 3;
2580 *tt++ = ix; *tt++ = 1; *tt++ = 3;
2583 GCDbuffer = NumberMalloc(
"MakeInteger");
2584 GCDbuffer2 = NumberMalloc(
"MakeInteger");
2585 LCMbuffer = NumberMalloc(
"MakeInteger");
2586 LCMbuffer2 = NumberMalloc(
"MakeInteger");
2588 tnext = t + *t; length = tnext[-1];
2589 if ( length < 0 ) { sign = -1; length = -length; }
2591 tstop = tnext - length;
2592 redlength = (length-1)/2;
2593 for ( i = 0; i < redlength; i++ ) {
2594 GCDbuffer[i] = (UWORD)(tstop[i]);
2595 LCMbuffer[i] = (UWORD)(tstop[redlength+i]);
2597 GCDlen = LCMlen = redlength;
2598 while ( GCDbuffer[GCDlen-1] == 0 ) GCDlen--;
2599 while ( LCMbuffer[LCMlen-1] == 0 ) LCMlen--;
2602 tnext = t + *t; length = ABS(tnext[-1]);
2603 tstop = tnext - length; redlength = (length-1)/2;
2604 len1 = len2 = redlength;
2605 den = tstop + redlength;
2606 while ( tstop[len1-1] == 0 ) len1--;
2607 while ( den[len2-1] == 0 ) len2--;
2608 if ( GCDlen == 1 && GCDbuffer[0] == 1 ) {}
2610 GcdLong(BHEAD (UWORD *)tstop,len1,GCDbuffer,GCDlen,GCDbuffer2,&GCDlen2);
2611 ap = GCDbuffer; GCDbuffer = GCDbuffer2; GCDbuffer2 = ap;
2612 a = GCDlen; GCDlen = GCDlen2; GCDlen2 = a;
2614 if ( len2 == 1 && den[0] == 1 ) {}
2616 GcdLong(BHEAD LCMbuffer,LCMlen,(UWORD *)den,len2,LCMbuffer2,&LCMlen2);
2617 DivLong((UWORD *)den,len2,LCMbuffer2,LCMlen2,
2618 GCDbuffer2,&GCDlen2,(UWORD *)AT.WorkPointer,&a);
2619 MulLong(LCMbuffer,LCMlen,GCDbuffer2,GCDlen2,LCMbuffer2,&LCMlen2);
2620 ap = LCMbuffer; LCMbuffer = LCMbuffer2; LCMbuffer2 = ap;
2621 a = LCMlen; LCMlen = LCMlen2; LCMlen2 = a;
2625 if ( GCDlen != 1 || GCDbuffer[0] != 1 || LCMlen != 1 || LCMbuffer[0] != 1 ) {
2626 redlength = GCDlen;
if ( LCMlen > GCDlen ) redlength = LCMlen;
2627 for ( i = 0; i < GCDlen; i++ ) *tout++ = (WORD)(GCDbuffer[i]);
2628 for ( ; i < redlength; i++ ) *tout++ = 0;
2629 for ( i = 0; i < LCMlen; i++ ) *tout++ = (WORD)(LCMbuffer[i]);
2630 for ( ; i < redlength; i++ ) *tout++ = 0;
2631 *tout++ = (2*redlength+1)*sign;
2632 for ( i = 0; i < LCMlen; i++ ) *tt++ = (WORD)(LCMbuffer[i]);
2633 for ( ; i < redlength; i++ ) *tt++ = 0;
2634 for ( i = 0; i < GCDlen; i++ ) *tt++ = (WORD)(GCDbuffer[i]);
2635 for ( ; i < redlength; i++ ) *tt++ = 0;
2636 *tt++ = (2*redlength+1)*sign;
2640 *tout++ = 1; *tout++ = 1; *tout++ = 3*sign;
2641 *tt++ = 1; *tt++ = 1; *tt++ = 3*sign;
2642 if ( sign != 1 ) action++;
2644 NumberFree(LCMbuffer2,
"MakeInteger");
2645 NumberFree(LCMbuffer ,
"MakeInteger");
2646 NumberFree(GCDbuffer2,
"MakeInteger");
2647 NumberFree(GCDbuffer ,
"MakeInteger");
2654 *term = tout - term; *tout = 0;
2655 *tterm = tt - tterm; *tt = 0;
2656 AT.WorkPointer = tt;
2657 inp = MultiplyWithTerm(BHEAD in,tterm,2);
2658 AT.WorkPointer = tterm;
2659 t = inp;
while ( *t ) t += *t;
2660 j = (t-inp); t = inp;
2661 if ( j*
sizeof(WORD) > (size_t)(AM.MaxTer) )
goto OverWork;
2662 in = tout = TermMalloc(
"TakeSymbolContent");
2663 NCOPY(tout,t,j); *tout = 0;
2664 if ( AN.tryterm > 0 ) { TermFree(inp,
"MultiplyWithTerm"); AN.tryterm = 0; }
2665 else { M_free(inp,
"MultiplyWithTerm"); }
2668 t = in;
while ( *t ) t += *t;
2670 if ( j*
sizeof(WORD) > (size_t)(AM.MaxTer) )
goto OverWork;
2671 in = tout = TermMalloc(
"TakeSymbolContent");
2672 NCOPY(tout,t,j); *tout = 0;
2673 term[0] = 4; term[1] = 1; term[2] = 1; term[3] = 3; term[4] = 0;
2679 AT.WorkPointer = oldworkpointer;
2683 MLOCK(ErrorMessageLock);
2684 MesPrint(
"Term too complex. Maybe increasing MaxTermSize can help");
2685 MUNLOCK(ErrorMessageLock);
2687 MLOCK(ErrorMessageLock);
2688 MesCall(
"TakeSymbolContent");
2689 MUNLOCK(ErrorMessageLock);
2703void GCDclean(PHEAD WORD *num, WORD *den)
2705 WORD *out1 = TermMalloc(
"GCDclean");
2706 WORD *out2 = TermMalloc(
"GCDclean");
2707 WORD *t1, *t2, *r1, *r2, *t1stop, *t2stop, csize1, csize2, csize3, pow, sign;
2709 t1stop = num+*num; sign = ( t1stop[-1] < 0 ) ? -1 : 1;
2710 csize1 = ABS(t1stop[-1]); t1stop -= csize1;
2711 t2stop = den+*den;
if ( t2stop[-1] < 0 ) sign = -sign;
2712 csize2 = ABS(t2stop[-1]); t2stop -= csize2;
2713 t1 = num+1; t2 = den+1;
2714 r1 = out1+3; r2 = out2+3;
2715 if ( t1 == t1stop ) {
2716 if ( t2 < t2stop ) {
2717 for ( i = 2; i < t2[1]; i += 2 ) {
2718 if ( t2[i+1] < 0 ) { *r1++ = t2[i]; *r1++ = -t2[i+1]; }
2719 else { *r2++ = t2[i]; *r2++ = t2[i+1]; }
2723 else if ( t2 == t2stop ) {
2724 for ( i = 2; i < t1[1]; i += 2 ) {
2725 if ( t1[i+1] < 0 ) { *r2++ = t1[i]; *r2++ = -t1[i+1]; }
2726 else { *r1++ = t1[i]; *r1++ = t1[i+1]; }
2731 while ( t1 < t1stop && t2 < t2stop ) {
2733 if ( t1[1] > 0 ) { *r1++ = *t1; *r1++ = t1[1]; t1 += 2; }
2734 else if ( t1[1] < 0 ) { *r2++ = *t1; *r2++ = -t1[1]; t1 += 2; }
2736 else if ( *t1 > *t2 ) {
2737 if ( t2[1] > 0 ) { *r2++ = *t2; *r2++ = t2[1]; t2 += 2; }
2738 else if ( t2[1] < 0 ) { *r1++ = *t2; *r1++ = -t2[1]; t2 += 2; }
2742 if ( pow > 0 ) { *r1++ = *t1; *r1++ = pow; }
2743 else if ( pow < 0 ) { *r2++ = *t1; *r2++ = -pow; }
2747 while ( t1 < t1stop ) {
2748 if ( t1[1] < 0 ) { *r2++ = *t1; *r2++ = -t1[1]; }
2749 else { *r1++ = *t1; *r1++ = t1[1]; }
2752 while ( t2 < t2stop ) {
2753 if ( t2[1] < 0 ) { *r1++ = *t2; *r1++ = -t2[1]; }
2754 else { *r2++ = *t2; *r2++ = t2[1]; }
2758 if ( r1 > out1+3 ) { out1[1] = SYMBOL; out1[2] = r1 - out1 - 1; }
2760 if ( r2 > out2+3 ) { out2[1] = SYMBOL; out2[2] = r2 - out2 - 1; }
2765 csize1 = REDLENG(csize1);
2766 csize2 = REDLENG(csize2);
2767 if ( DivRat(BHEAD (UWORD *)t1stop,csize1,(UWORD *)t2stop,csize2,(UWORD *)r1,&csize3) ) {
2768 MLOCK(ErrorMessageLock);
2769 MesCall(
"GCDclean");
2770 MUNLOCK(ErrorMessageLock);
2773 UnPack((UWORD *)r1,csize3,&csize2,&csize1);
2774 t2 = r1+ABS(csize3);
2775 for ( i = 0; i < csize2; i++ ) r2[i] = t2[i];
2776 r2 += csize2; *r2++ = 1;
2777 for ( i = 1; i < csize2; i++ ) *r2++ = 0;
2778 csize2 = INCLENG(csize2); *r2++ = csize2; *out2 = r2-out2;
2779 r1 += ABS(csize1); *r1++ = 1;
2780 for ( i = 1; i < ABS(csize1); i++ ) *r1++ = 0;
2781 csize1 = INCLENG(csize1); *r1++ = csize1; *out1 = r1-out1;
2783 t1 = num; t2 = out1; i = *out1; NCOPY(t1,t2,i); *t1 = 0;
2784 if ( sign < 0 ) t1[-1] = -t1[-1];
2785 t1 = den; t2 = out2; i = *out2; NCOPY(t1,t2,i); *t1 = 0;
2787 TermFree(out2,
"GCDclean");
2788 TermFree(out1,
"GCDclean");
2800WORD *PolyDiv(PHEAD WORD *a,WORD *b,
char *text)
2806 return(poly_div(BHEAD a,b,1));
2845WORD divrem[4] = { DIVFUNCTION, REMFUNCTION, INVERSEFUNCTION, MULFUNCTION };
2847int DIVfunction(PHEAD WORD *term,WORD level,
int par)
2850 WORD *t, *tt, *r, *arg1 = 0, *arg2 = 0, *arg3 = 0, *termout;
2851 WORD *tstop, *tend, *r3, *rr, *rstop, tlength, rlength, newlength;
2852 WORD *proper1, *proper2, *proper3 = 0, numdol = -1;
2853 int numargs = 0, type1, type2, actionflag1, actionflag2;
2854 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2855 int division = ( par <= 2 );
2856 if ( par < 0 || par > 3 ) {
2858 MLOCK(ErrorMessageLock);
2859 MesPrint(
"!>Internal error. Illegal parameter %d in DIVfunction.",par);
2860 MUNLOCK(ErrorMessageLock);
2867 tend = term + *term; tstop = tend - ABS(tend[-1]);
2869 while ( t < tstop ) {
2870 if ( *t != divrem[par] ) { t += t[1];
continue; }
2872 tt = t + t[1]; numargs = 0;
2874 if ( numargs == 0 ) { arg1 = r; }
2875 if ( numargs == 1 ) { arg2 = r; }
2876 if ( numargs == 2 && *r == -DOLLAREXPRESSION ) { numdol = r[1]; }
2880 if ( numargs == 2 )
break;
2881 if ( division && numargs == 3 )
break;
2886 MLOCK(ErrorMessageLock);
2887 MesPrint(
"!>Internal error. Indicated div_ or rem_ function not encountered.");
2888 MUNLOCK(ErrorMessageLock);
2895 if ( division && *arg1 == -SNUMBER && arg1[1] == 0 ) {
2896 if ( *arg2 == -SNUMBER && arg2[1] == 0 ) {
2898 MLOCK(ErrorMessageLock);
2899 MesPrint(
"0/0 in either div_ or rem_ function.");
2900 MUNLOCK(ErrorMessageLock);
2903 if ( numdol >= 0 ) PutTermInDollar(0,numdol);
2906 if ( division && *arg2 == -SNUMBER && arg2[1] == 0 ) {
2908 MLOCK(ErrorMessageLock);
2909 MesPrint(
"Division by zero in either div_ or rem_ function.");
2910 MUNLOCK(ErrorMessageLock);
2914 if ( (*arg1 == -SNUMBER && arg1[1] == 0) ||
2915 (*arg2 == -SNUMBER && arg2[1] == 0) ) {
2919 if ( ( arg1 = ConvertArgument(BHEAD arg1, &type1) ) == 0 )
goto CalledFrom;
2920 if ( ( arg2 = ConvertArgument(BHEAD arg2, &type2) ) == 0 )
goto CalledFrom;
2921 if ( division && *arg1 == 0 ) {
2923 M_free(arg2,
"DIVfunction");
2924 M_free(arg1,
"DIVfunction");
2927 M_free(arg2,
"DIVfunction");
2928 M_free(arg1,
"DIVfunction");
2929 if ( numdol >= 0 ) PutTermInDollar(0,numdol);
2932 if ( division && *arg2 == 0 ) {
2933 M_free(arg2,
"DIVfunction");
2934 M_free(arg1,
"DIVfunction");
2937 if ( !division && (*arg1 == 0 || *arg2 == 0) ) {
2938 M_free(arg2,
"DIVfunction");
2939 M_free(arg1,
"DIVfunction");
2942 if ( ( proper1 = PutExtraSymbols(BHEAD arg1,startebuf,&actionflag1) ) == 0 )
goto CalledFrom;
2943 if ( ( proper2 = PutExtraSymbols(BHEAD arg2,startebuf,&actionflag2) ) == 0 )
goto CalledFrom;
2952 M_free(arg2,
"DIVfunction");
2961 M_free(arg1,
"DIVfunction");
2962 if ( par == 0 ) proper3 = poly_div(BHEAD proper1, proper2,0);
2963 else if ( par == 1 ) proper3 = poly_rem(BHEAD proper1, proper2,0);
2964 else if ( par == 2 ) proper3 = poly_inverse(BHEAD proper1, proper2);
2965 else if ( par == 3 ) proper3 = poly_mul(BHEAD proper1, proper2);
2966 if ( proper3 == 0 )
goto CalledFrom;
2967 if ( actionflag1 || actionflag2 ) {
2968 if ( ( arg3 = TakeExtraSymbols(BHEAD proper3,startebuf) ) == 0 )
goto CalledFrom;
2969 M_free(proper3,
"DIVfunction");
2974 M_free(proper2,
"DIVfunction");
2975 M_free(proper1,
"DIVfunction");
2976 cbuf[AT.ebufnum].numrhs = startebuf;
2978 termout = AT.WorkPointer;
2980 tlength = REDLENG(tlength);
2983 tt = term + 1; rr = termout + 1;
2984 while ( tt < t ) *rr++ = *tt++;
2987 rstop = r3 - ABS(r3[-1]);
2988 while ( r < rstop ) *rr++ = *r++;
2990 while ( tt < tstop ) *rr++ = *tt++;
2992 rlength = REDLENG(rlength);
2993 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)rstop,rlength,
2994 (UWORD *)rr,&newlength) < 0 )
goto CalledFrom;
2995 rlength = INCLENG(newlength);
2998 *termout = rr - termout;
2999 AT.WorkPointer = rr;
3000 if (
Generator(BHEAD termout,level) )
goto CalledFrom;
3002 AT.WorkPointer = termout;
3004 M_free(arg3,
"DIVfunction");
3007 MLOCK(ErrorMessageLock);
3008 MesCall(
"DIVfunction");
3009 MUNLOCK(ErrorMessageLock);
3020WORD *MULfunc(PHEAD WORD *p1, WORD *p2)
3022 WORD *prod,size1,size2,size3,*t,*tfill,*ps1,*ps2,sign1,sign2, error, *p3;
3023 UWORD *num1, *num2, *num3;
3025 WORD oldsorttype = AR.SortType;
3026 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
3027 AR.SortType = SORTHIGHFIRST;
3029 num3 = NumberMalloc(
"MULfunc");
3030 prod = TermMalloc(
"MULfunc");
3033 ps1 = p1+*p1; num1 = (UWORD *)(ps1 - ABS(ps1[-1])); size1 = ps1[-1];
3034 if ( size1 < 0 ) { sign1 = -1; size1 = -size1; }
3036 size1 = (size1-1)/2;
3039 ps2 = p3+*p3; num2 = (UWORD *)(ps2 - ABS(ps2[-1])); size2 = ps2[-1];
3040 if ( size2 < 0 ) { sign2 = -1; size2 = -size2; }
3042 size2 = (size2-1)/2;
3043 if ( MulLong(num1,size1,num2,size2,num3,&size3) ) {
3047 MLOCK(ErrorMessageLock);
3048 MesPrint(
"!>Error %d",error);
3050 MUNLOCK(ErrorMessageLock);
3055 t = p1+1;
while ( t < (WORD *)num1 ) *tfill++ = *t++;
3056 t = p3+1;
while ( t < (WORD *)num2 ) *tfill++ = *t++;
3058 for ( i = 0; i < size3; i++ ) *tfill++ = *t++;
3060 for ( i = 1; i < size3; i++ ) *tfill++ = 0;
3061 *tfill++ = (2*size3+1)*sign1*sign2;
3062 prod[0] = tfill - prod;
3064 if (
StoreTerm(BHEAD prod) ) { error = 3;
goto CalledFrom; }
3069 NumberFree(num3,
"MULfunc");
3071 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
3072 AR.SortType = oldsorttype;
3083WORD *ConvertArgument(PHEAD WORD *arg,
int *type)
3085 WORD *output, *t, *r;
3088 output = (WORD *)Malloc1((*arg)*
sizeof(WORD),
"ConvertArgument");
3089 i = *arg - ARGHEAD; t = arg + ARGHEAD; r = output;
3094 if ( *arg == -EXPRESSION ) {
3096 return(CreateExpression(BHEAD arg[1]));
3098 if ( *arg == -DOLLAREXPRESSION ) {
3101 d = DolToTerms(BHEAD arg[1]);
3107 output = (WORD *)Malloc1((d->size+1)*
sizeof(WORD),
"Copy of dollar content");
3108 WCOPY(output,d->where,d->size+1);
3109 if ( d->factors ) { M_free(d->factors,
"Dollar factors"); d->factors = 0; }
3110 M_free(d,
"Copy of dollar variable");
3118 output = (WORD *)Malloc1(size*
sizeof(WORD),
"ConvertArgument");
3121 output[0] = 8; output[1] = SYMBOL; output[2] = 4; output[3] = arg[1];
3122 output[4] = 1; output[5] = 1; output[6] = 1; output[7] = 3;
3128 output[0] = 7; output[1] = INDEX; output[2] = 3; output[3] = arg[1];
3129 output[4] = 1; output[5] = 1;
3130 if ( *arg == -MINVECTOR ) output[6] = -3;
3137 output[1] = -arg[1]; output[2] = 1; output[3] = -3;
3140 output[1] = arg[1]; output[2] = 1; output[3] = 3;
3145 output[0] = FUNHEAD+4;
3147 output[2] = FUNHEAD;
3148 for ( i = 3; i <= FUNHEAD; i++ ) output[i] = 0;
3149 output[FUNHEAD+1] = 1;
3150 output[FUNHEAD+2] = 1;
3151 output[FUNHEAD+3] = 3;
3152 output[FUNHEAD+4] = 0;
3170char *TheErrorMessage[] = {
3171 "PolyRatFun not of a type that FORM will expand: incorrect variable inside."
3172 ,
"Division by zero in PolyRatFun encountered in ExpandRat."
3173 ,
"Irregular code in PolyRatFun encountered in ExpandRat."
3174 ,
"Called from ExpandRat."
3175 ,
"WorkSpace overflow. Change parameter WorkSpace in setup file?"
3176 ,
"Illegal term in expanded polyratfun."
3179int ExpandRat(PHEAD WORD *fun)
3181 WORD *r, *rr, *rrr, *tt, *tnext, *arg1, *arg2, *rmin = NULL, *rmininv;
3182 WORD *rcoef, rsize, rcopy, *ow = AT.WorkPointer;
3183 WORD *numerator, *denominator, *rnext;
3184 WORD *thecopy, *rc, ncoef, newcoef, *m, *mm, nco, *outarg = NULL;
3185 UWORD co[2], co1[2], co2[2];
3186 WORD OldPolyFunPow = AR.PolyFunPow;
3187 int i, j, minpow = 0, eppow, first, error = 0, ipoly;
3188 if ( fun[1] == FUNHEAD ) {
return(0); }
3189 tnext = fun + fun[1];
3190 if ( fun[1] == fun[FUNHEAD]+FUNHEAD ) {
3191 if ( fun[2] == 0 ) {
goto done; }
3196 if ( outarg == NULL ) outarg = TermMalloc(
"ExpandRat")+ARGHEAD;
3199 r = fun+FUNHEAD+ARGHEAD;
3200 if ( AR.PolyFunExp == 2 ) {
3201 WORD minpow2 = MAXPOWER, *rrm;
3203 while ( rrm < tnext ) {
3205 if ( minpow2 > 0 ) minpow2 = 0;
3207 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3208 if ( minpow2 > 0 ) minpow2 = 0;
3211 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3212 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3214 else { error = 5;
goto onerror; }
3218 AR.PolyFunPow += minpow2;
3220 while ( r < tnext ) {
3222 i = *r; rrr = outarg; NCOPY(rrr,r,i);
3223 Normalize(BHEAD outarg);
3224 if ( *outarg > 0 )
StoreTerm(BHEAD outarg);
3226 r = fun+FUNHEAD+ARGHEAD;
3230 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = 0;
3235 if ( ToFast(rr,rr) ) {
3236 NEXTARG(rr); fun[1] = rr - fun;
3239 while ( *r ) r += *r;
3240 *rr = r-rr; rr[1] = CLEANFLAG;
3253 arg1 = tt; NEXTARG(tt);
3255 arg2 = tt; NEXTARG(tt);
3256 if ( tt != tnext ) { arg1 = arg2 = NULL; }
3258 }
else { error = 5;
goto onerror; }
3259 if ( arg2 == NULL ) {
3260 if ( *arg1 < 0 ) { fun[2] = CLEANFLAG;
goto done; }
3261 if ( fun[2] == CLEANFLAG )
goto done;
3267 if ( outarg == NULL ) outarg = TermMalloc(
"ExpandRat")+ARGHEAD;
3276 if ( *arg2 == -SYMBOL && arg2[1] == AR.PolyFunVar ) {
3277 rr = r = fun+FUNHEAD+ARGHEAD;
3279 if ( *arg1 == -SYMBOL ) {
3280 if ( arg1[1] == AR.PolyFunVar ) {
3281 *r++ = 4; *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3284 *r++ = 10; *r++ = SYMBOL; *r++ = 6;
3285 *r++ = arg1[1]; *r++ = 1;
3286 *r++ = AR.PolyFunVar; *r++ = -1;
3287 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3288 Normalize(BHEAD rr);
3291 else if ( *arg1 == -SNUMBER ) {
3293 if ( nco == 0 ) { *r++ = 0; }
3295 *r++ = 8; *r++ = SYMBOL; *r++ = 4;
3296 *r++ = AR.PolyFunVar; *r++ = -1;
3297 *r++ = ABS(nco); *r++ = 1;
3298 if ( nco < 0 ) *r++ = -3;
3303 else { error = 2;
goto onerror; }
3308 if ( AR.PolyFunExp == 2 ) {
3309 WORD minpow2 = MAXPOWER, *rrm;
3311 while ( rrm < arg2 ) {
3313 if ( minpow2 > 0 ) minpow2 = 0;
3315 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3316 if ( minpow2 > 0 ) minpow2 = 0;
3319 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3320 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3322 else { error = 5;
goto onerror; }
3326 AR.PolyFunPow += minpow2-1;
3328 while ( m < arg2 ) {
3330 rrr = r++; mm = m + *m;
3331 *r++ = SYMBOL; *r++ = 4; *r++ = AR.PolyFunVar; *r++ = -1;
3332 m++;
while ( m < mm ) *r++ = *m++;
3334 Normalize(BHEAD rrr);
3338 r = rr;
while ( *r ) r += *r;
3341 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = CLEANFLAG;
3348 if ( ToFast(rr,rr) ) {
3352 else { fun[1] = r - fun; }
3357 else if ( *arg2 == -SNUMBER ) {
3359 if ( arg2[1] == 0 ) { error = 1;
goto onerror; }
3360 if ( *arg1 == -SNUMBER ) {
3361 if ( arg1[1] == 0 ) { *r++ = 0; }
3363 co1[0] = ABS(arg1[1]); co1[1] = 1;
3364 co2[0] = 1; co2[1] = ABS(arg2[1]);
3365 MulRat(BHEAD co1,1,co2,1,co,&nco);
3366 *r++ = 4; *r++ = (WORD)(co[0]); *r++ = (WORD)(co[1]);
3367 if ( ( arg1[1] < 0 && arg2[1] > 0 ) ||
3368 ( arg1[1] > 0 && arg2[1] < 0 ) ) *r++ = -3;
3373 else if ( *arg1 == -SYMBOL ) {
3374 *r++ = 8; *r++ = SYMBOL; *r++ = 4;
3375 *r++ = arg1[1]; *r++ = 1;
3376 *r++ = 1; *r++ = ABS(arg2[1]);
3377 if ( arg2[1] < 0 ) *r++ = -3;
3381 else if ( *arg1 < 0 ) { error = 2;
goto onerror; }
3385 if ( AR.PolyFunExp == 2 ) {
3386 WORD minpow2 = MAXPOWER, *rrm;
3388 while ( rrm < arg2 ) {
3390 if ( minpow2 > 0 ) minpow2 = 0;
3392 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3393 if ( minpow2 > 0 ) minpow2 = 0;
3396 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3397 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3399 else { error = 5;
goto onerror; }
3403 AR.PolyFunPow += minpow2;
3405 while ( m < arg2 ) {
3407 rrr = r++; mm = m + *m;
3408 *r++ = DENOMINATOR; *r++ = FUNHEAD + 2; *r++ = DIRTYFLAG;
3410 *r++ = arg2[0]; *r++ = arg2[1];
3411 m++;
while ( m < mm ) *r++ = *m++;
3413 if ( r < AT.WorkTop && r >= AT.WorkSpace )
3415 Normalize(BHEAD rrr);
3416 if ( ABS(rrr[*rrr-1]) == *rrr-1 ) {
3417 if ( AR.PolyFunPow >= 0 ) {
3421 else if ( rrr[1] == SYMBOL && rrr[2] == 4 &&
3422 rrr[3] == AR.PolyFunVar && rrr[4] <= AR.PolyFunPow ) {
3428 r = rr;
while ( *r ) r += *r;
3430 r = fun + FUNHEAD + ARGHEAD;
3433 *rr = r - rr; rr[1] = CLEANFLAG;
3434 if ( ToFast(rr,rr) ) {
3438 else { fun[1] = r - fun; }
3442 else { error = 0;
goto onerror; }
3447 while ( r < tnext ) {
3448 rr = r + *r; rr -= ABS(rr[-1]);
3450 if ( first ) { minpow = 0; first = 0; rmin = r; }
3451 else if ( minpow > 0 ) { minpow = 0; rmin = r; }
3453 else if ( r[1] != SYMBOL || r[2] != 4 || r[3] != AR.PolyFunVar
3454 || r[4] > MAXPOWER ) { error = 0;
goto onerror; }
3455 else if ( first ) { minpow = r[4]; first = 0; rmin = r; }
3456 else if ( r[4] < minpow ) { minpow = r[4]; rmin = r; }
3474 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
3475 if ( AT.WorkPointer + (AM.MaxTer/
sizeof(WORD)) >= AT.WorkTop ) {
3476 error = 4;
goto onerror;
3478 rmininv = r = AT.WorkPointer;
3479 rr = rmin; i = *rmin; NCOPY(r,rr,i)
3480 if ( minpow != 0 ) { rmininv[4] = -rmininv[4]; }
3483 rsize = (rsize-1)/2; rr = rcoef + rsize;
3484 for ( i = 0; i < rsize; i++ ) {
3485 rcopy = rcoef[i]; rcoef[i] = rr[i]; rr[i] = rcopy;
3489 ToGeneral(arg1,r,0);
3490 arg1 = r; r += *r; *r++ = 0; rcopy = 0;
3495 rcopy = *r; *r++ = 0;
3500 AT.LeaveNegative = 1;
3501 numerator = MultiplyWithTerm(BHEAD arg1+ARGHEAD,rmininv,0);
3502 AT.LeaveNegative = 0;
3504 r = numerator;
while ( *r ) r += *r;
3505 AT.WorkPointer = r+1;
3506 rcopy = arg2[*arg2]; arg2[*arg2] = 0;
3507 denominator = MultiplyWithTerm(BHEAD arg2+ARGHEAD,rmininv,1);
3508 arg2[*arg2] = rcopy;
3509 r = denominator;
while ( *r ) r += *r;
3510 AT.WorkPointer = r+1;
3517 rr = r + *r; rr -= ABS(rr[-1]);
3519 if ( first ) { minpow = 0; first = 0; }
3520 else if ( minpow > 0 ) { minpow = 0; }
3522 else if ( r[1] != SYMBOL ) { error = 0;
goto onerror; }
3524 for ( i = 3; i < r[2]; i += 2 ) {
3525 if ( r[i] == AR.PolyFunVar ) {
3526 if ( first ) { minpow = r[i+1]; first = 0; }
3527 else if ( r[i+1] < minpow ) minpow = r[i+1];
3532 if ( first ) { minpow = 0; first = 0; }
3533 else if ( minpow > 0 ) minpow = 0;
3543 if ( AR.PolyFunExp == 3 ) {
3544 ipoly = InvPoly(BHEAD denominator,AR.PolyFunPow-minpow,AR.PolyFunVar);
3547 ipoly = InvPoly(BHEAD denominator,AR.PolyFunPow,AR.PolyFunVar);
3559 rrr = rnext - ABS(rnext[-1]);
3563 j = rr[1] - 2; rr += 2;
3565 if ( *rr == AR.PolyFunVar ) { eppow = rr[1];
break; }
3572 for ( i = 0; i <= AR.PolyFunPow-eppow+minpow; i++ ) {
3573 if ( AT.pWorkSpace[ipoly+i] == 0 )
continue;
3578 rr = thecopy = AT.WorkPointer;
3579 while ( rc < rrr ) *rr++ = *rc++;
3581 *rr++ = SYMBOL; *rr++ = 4; *rr++ = AR.PolyFunVar; *rr++ = i;
3583 ncoef = REDLENG(rnext[-1]);
3584 MulRat(BHEAD (UWORD *)rrr,ncoef,
3585 (UWORD *)(AT.pWorkSpace[ipoly+i])+1,AT.pWorkSpace[ipoly+i][0]
3586 ,(UWORD *)rr,&newcoef);
3587 ncoef = ABS(newcoef); rr += 2*ncoef;
3588 newcoef = INCLENG(newcoef);
3590 *thecopy = rr - thecopy;
3591 AT.WorkPointer = rr;
3592 Normalize(BHEAD thecopy);
3593 if ( *thecopy > 0 )
StoreTerm(BHEAD thecopy);
3594 AT.WorkPointer = thecopy;
3601 rr = fun + FUNHEAD; r = rr + ARGHEAD;
3604 fun[1] = FUNHEAD+2; fun[2] = CLEANFLAG;
3605 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = 0;
3608 while ( *r ) r += *r;
3609 rr[0] = r-rr; rr[1] = CLEANFLAG;
3610 if ( ToFast(rr,rr) ) { NEXTARG(rr); fun[1] = rr-fun; }
3611 else { fun[1] = r-fun; }
3616 if ( outarg ) TermFree(outarg-ARGHEAD,
"ExpandRat");
3617 AR.PolyFunPow = OldPolyFunPow;
3618 AT.WorkPointer = ow;
3619 AN.PolyNormFlag = 1;
3622 if ( outarg ) TermFree(outarg-ARGHEAD,
"ExpandRat");
3623 AR.PolyFunPow = OldPolyFunPow;
3624 AT.WorkPointer = ow;
3625 MLOCK(ErrorMessageLock);
3626 MesPrint(TheErrorMessage[error]);
3627 MUNLOCK(ErrorMessageLock);
3649int InvPoly(PHEAD WORD *inpoly, WORD maxpow, WORD sym)
3651 int needed, inpointers, outpointers, maxinput = 0, i, j;
3652 WORD *t, *tt, *ttt, *w, *c, *cc, *ccc, lenc, lenc1, lenc2, rc, *c1, *c2;
3656 needed = (maxpow+1)*2;
3657 WantAddPointers(needed);
3658 inpointers = AT.pWorkPointer;
3659 outpointers = AT.pWorkPointer+maxpow+1;
3660 for ( i = 0; i < needed; i++ ) AT.pWorkSpace[inpointers+i] = 0;
3670 if ( t[1] != 1 || t[2] != 1 || t[3] != 3 )
goto onerror;
3671 AT.pWorkSpace[inpointers] = 0;
3673 else if ( t[1] != SYMBOL || t[2] != 4 || t[3] != sym || t[4] < 0 )
goto onerror;
3674 else if ( t[4] > maxpow ) {}
3676 if ( t[4] > maxinput ) maxinput = t[4];
3677 AT.pWorkSpace[inpointers+t[4]] = w;
3678 tt = t + *t; rc = -*--tt;
3679 rc = REDLENG(rc); *w++ = rc;
3681 while ( ttt < tt ) *w++ = *ttt++;
3689 AT.pWorkSpace[outpointers] = w;
3690 *w++ = 1; *w++ = 1; *w++ = 1;
3691 c = TermMalloc(
"InvPoly");
3692 c1 = TermMalloc(
"InvPoly");
3693 c2 = TermMalloc(
"InvPoly");
3694 for ( j = 1; j <= maxpow; j++ ) {
3698 if ( ( cc = AT.pWorkSpace[inpointers+j] ) != 0 ) {
3700 i = 2*ABS(lenc); ccc = c;
3704 for ( i = MiN(j-1,maxinput); i > 0; i-- ) {
3708 if ( AT.pWorkSpace[inpointers+i] == 0
3709 || AT.pWorkSpace[outpointers+j-i] == 0 ) {
3712 if ( MulRat(BHEAD (UWORD *)(AT.pWorkSpace[inpointers+i]+1),AT.pWorkSpace[inpointers+i][0],
3713 (UWORD *)(AT.pWorkSpace[outpointers+j-i]+1),AT.pWorkSpace[outpointers+j-i][0],
3714 (UWORD *)c1,&lenc1) )
goto calcerror;
3716 cc = c; c = c1; c1 = cc;
3720 if ( AddRat(BHEAD (UWORD *)c,lenc,(UWORD *)c1,lenc1,(UWORD *)c2,&lenc2) )
3722 cc = c; c = c2; c2 = cc;
3730 if ( lenc == 0 ) AT.pWorkSpace[outpointers+j] = 0;
3732 AT.pWorkSpace[outpointers+j] = w;
3734 i = 2*ABS(lenc); ccc = c;
3739 TermFree(c2,
"InvPoly");
3740 TermFree(c1,
"InvPoly");
3741 TermFree(c ,
"InvPoly");
3743 return(outpointers);
3745 MLOCK(ErrorMessageLock);
3746 MesPrint(
"Incorrect symbol field in InvPoly.");
3747 MUNLOCK(ErrorMessageLock);
3751 MLOCK(ErrorMessageLock);
3752 MesPrint(
"Called from InvPoly.");
3753 MUNLOCK(ErrorMessageLock);
int LocalConvertToPoly(PHEAD WORD *, WORD *, WORD, WORD)
LONG EndSort(PHEAD WORD *, int)
int Generator(PHEAD WORD *, WORD)
void LowerSortLevel(void)
int StoreTerm(PHEAD WORD *)
int InsertTerm(PHEAD WORD *, WORD, WORD, WORD *, WORD *, WORD)
int GetModInverses(WORD, WORD, WORD *, WORD *)
WORD CompareSymbols(PHEAD WORD *, WORD *, WORD)
int SymbolNormalize(WORD *)
WORD * poly_gcd(PHEAD WORD *, WORD *, WORD)
WORD * TakeContent(PHEAD WORD *in, WORD *term)
WORD * TakeSymbolContent(PHEAD WORD *in, WORD *term)