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;
647 MLOCK(ErrorMessageLock);
648 MesPrint(
"Internal error. Indicated gcd_ function not encountered.");
649 MUNLOCK(ErrorMessageLock);
652 WantAddPointers(totargs);
653 args = AT.pWorkPointer; AT.pWorkPointer += totargs;
667 while ( tf < t + t[1] ) {
668 if ( *tf == -SNUMBER && tf[1] == 0 ) { NEXTARG(tf);
continue; }
669 if ( *tf > 0 || *tf == -DOLLAREXPRESSION || *tf == -EXPRESSION ) {
670 AT.pWorkSpace[args+numargs++] = tf;
671 NEXTARG(tf);
continue;
673 if ( firstshort == 0 ) {
675 if ( *tf <= -FUNCTION ) { firstvalue = -(*tf); }
676 else { firstvalue = tf[1]; }
681 else if ( *tf != firstshort ) {
682 if ( *tf != -INDEX && *tf != -VECTOR && *tf != -MINVECTOR ) {
683 argsdone++; gcdisone = 1;
break;
685 if ( firstshort != -INDEX && firstshort != -VECTOR && firstshort != -MINVECTOR ) {
686 argsdone++; gcdisone = 1;
break;
688 if ( tf[1] != firstvalue ) {
689 argsdone++; gcdisone = 1;
break;
691 if ( *t == -MINVECTOR ) { firstshort = -VECTOR; }
692 if ( firstshort == -MINVECTOR ) { firstshort = -VECTOR; }
694 else if ( *tf > -FUNCTION && *tf != -SNUMBER && tf[1] != firstvalue ) {
695 argsdone++; gcdisone = 1;
break;
697 if ( *tf == -SNUMBER && firstvalue != tf[1] ) {
701 if ( firstvalue == 1 || tf[1] == 1 ) { gcdisone = 1;
break; }
702 if ( firstvalue < 0 && tf[1] < 0 ) {
703 x1 = -firstvalue; x2 = -tf[1]; sign = -1;
706 x1 = ABS(firstvalue); x2 = ABS(tf[1]); sign = 1;
708 while ( ( x3 = x1%x2 ) != 0 ) { x1 = x2; x2 = x3; }
709 firstvalue = ((WORD)x2)*sign;
711 if ( firstvalue == 1 ) { gcdisone = 1;
break; }
715 termout = AT.WorkPointer;
716 AT.WorkPointer = (WORD *)(((UBYTE *)(AT.WorkPointer)) + AM.MaxTer);
717 if ( AT.WorkPointer > AT.WorkTop ) {
718 MLOCK(ErrorMessageLock);
720 MUNLOCK(ErrorMessageLock);
729 i = t - term; tin = term; tout = termout;
731 if ( gcdisone || ( firstshort == -SNUMBER && firstvalue == 1 ) ) {
734 tin += t[1]; tstop = term + *term;
735 while ( tin < tstop ) *tout++ = *tin++;
736 *termout = tout - termout;
737 if ( sign < 0 ) tout[-1] = -tout[-1];
738 AT.WorkPointer = tout;
739 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
740 AT.WorkPointer = termout;
741 AT.pWorkPointer = args;
748 if ( numargs == 0 ) {
751 if ( firstshort == 0 )
goto gcdone;
752 if ( firstshort == -SNUMBER ) {
753 *tout++ = SNUMBER; *tout++ = 4; *tout++ = firstvalue; *tout++ = 1;
756 else if ( firstshort == -SYMBOL ) {
757 *tout++ = SYMBOL; *tout++ = 4; *tout++ = firstvalue; *tout++ = 1;
760 else if ( firstshort == -VECTOR || firstshort == -INDEX ) {
761 *tout++ = INDEX; *tout++ = 3; *tout++ = firstvalue;
goto gcdone;
763 else if ( firstshort == -MINVECTOR ) {
765 *tout++ = INDEX; *tout++ = 3; *tout++ = firstvalue;
goto gcdone;
767 else if ( firstshort <= -FUNCTION ) {
768 *tout++ = firstvalue; *tout++ = FUNHEAD; FILLFUN(tout);
772 MLOCK(ErrorMessageLock);
773 MesPrint(
"Internal error. Illegal short argument in GCDfunction.");
774 MUNLOCK(ErrorMessageLock);
786 switch ( firstshort ) {
788 sh[0] = 4; sh[1] = ABS(firstvalue); sh[2] = 1;
789 if ( firstvalue < 0 ) sh[3] = -3;
796 sh[0] = 8; sh[1] = INDEX; sh[2] = 3; sh[3] = firstvalue;
797 sh[4] = 1; sh[5] = 1;
798 if ( firstshort == -MINVECTOR ) sh[6] = -3;
803 sh[0] = 8; sh[1] = SYMBOL; sh[2] = 4; sh[3] = firstvalue; sh[4] = 1;
804 sh[5] = 1; sh[6] = 1; sh[7] = 3; sh[8] = 0;
807 sh[0] = FUNHEAD+4; sh[1] = firstshort; sh[2] = FUNHEAD;
808 for ( i = 2; i < FUNHEAD; i++ ) sh[i+1] = 0;
809 sh[FUNHEAD+1] = 1; sh[FUNHEAD+2] = 1; sh[FUNHEAD+3] = 3; sh[FUNHEAD+4] = 0;
820 for ( i = 1; i < numargs; i++ ) {
821 for ( ii = i; ii > 0; ii-- ) {
822 arg1 = AT.pWorkSpace[args+ii];
823 arg2 = AT.pWorkSpace[args+ii-1];
826 if ( *arg1 == -EXPRESSION )
break;
827 if ( *arg2 == -DOLLAREXPRESSION )
break;
828 AT.pWorkSpace[args+ii] = arg2;
829 AT.pWorkSpace[args+ii-1] = arg1;
833 else if ( *arg2 < 0 ) {
834 AT.pWorkSpace[args+ii] = arg2;
835 AT.pWorkSpace[args+ii-1] = arg1;
838 if ( *arg1 > *arg2 ) {
839 AT.pWorkSpace[args+ii] = arg2;
840 AT.pWorkSpace[args+ii-1] = arg1;
853 for ( i = istart; i < numargs; i++ ) {
854 arg1 = AT.pWorkSpace[args+i];
856 oldval1 = arg1[*arg1]; arg1[*arg1] = 0;
859 GCDterms(BHEAD mh,m,mh); m += *m;
860 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
861 gcdisone = 1; sign = 1; arg1[*arg1] = oldval1;
goto gcdone;
864 arg1[*arg1] = oldval1;
866 else if ( *arg1 == -DOLLAREXPRESSION ) {
867 if ( ( d = DolToTerms(BHEAD arg1[1]) ) != 0 ) {
870 GCDterms(BHEAD mh,m,mh); m += *m;
872 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
873 gcdisone = 1; sign = 1;
874 if ( d->factors ) M_free(d->factors,
"Dollar factors");
875 M_free(d,
"Copy of dollar variable");
goto gcdone;
878 if ( d->factors ) M_free(d->factors,
"Dollar factors");
879 M_free(d,
"Copy of dollar variable");
883 mm = CreateExpression(BHEAD arg1[1]);
886 GCDterms(BHEAD mh,m,mh); m += *m;
888 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
889 gcdisone = 1; sign = 1; M_free(mm,
"CreateExpression");
goto gcdone;
892 M_free(mm,
"CreateExpression");
897 firstshort = -SNUMBER; firstvalue = mh[1] * (mh[3]/3);
899 else if ( mh[1] == SYMBOL ) {
900 firstshort = -SYMBOL; firstvalue = mh[3];
902 else if ( mh[1] == INDEX ) {
903 firstshort = -INDEX; firstvalue = mh[3];
904 if ( mh[6] == -3 ) firstshort = -MINVECTOR;
906 else if ( mh[1] >= FUNCTION ) {
907 firstshort = -mh[1]; firstvalue = mh[1];
928 for ( i = 0; i < numargs; i++ ) {
929 arg1 = AT.pWorkSpace[args+i];
930 if ( *arg1 > 0 && arg1[ARGHEAD]+ARGHEAD == *arg1 ) {
935 arg2 = AT.pWorkSpace[args];
936 AT.pWorkSpace[args] = arg1;
937 AT.pWorkSpace[args+1] = arg2;
939 m = mh = AT.WorkPointer;
940 mm = arg1+ARGHEAD; i = *mm;
961 for ( i = 0; i < numargs; i++ ) {
962 arg1 = AT.pWorkSpace[args+i];
964 m = (WORD *)Malloc1(*arg1*
sizeof(WORD),
"argbuffer type 0");
974 else if ( *arg1 == -DOLLAREXPRESSION ) {
975 d = DolToTerms(BHEAD arg1[1]);
976 abuf[i].buffer = d->where;
980 if ( *m ) argsdone++;
982 abuf[i].size = m-abuf[i].buffer;
984 else if ( *arg1 == -EXPRESSION ) {
985 abuf[i].buffer = CreateExpression(BHEAD arg1[1]);
988 if ( *m ) argsdone++;
990 abuf[i].size = m-abuf[i].buffer;
993 MLOCK(ErrorMessageLock);
994 MesPrint(
"What argument is this?");
995 MUNLOCK(ErrorMessageLock);
999 for ( i = 0; i < numargs; i++ ) {
1000 arg1 = abuf[i].buffer;
1001 if ( *arg1 == 0 ) {}
1002 else if ( arg1[*arg1] == 0 ) {
1006 ab = abuf[i]; abuf[i] = abuf[0]; abuf[0] = ab;
1007 mh = abuf[0].buffer;
1008 for ( j = 1; j < numargs; j++ ) {
1011 GCDterms(BHEAD mh,m,mh); m += *m;
1013 if ( mh[0] == 4 && mh[1] == 1 && mh[2] == 1 && mh[3] == 3 ) {
1014 gcdisone = 1; sign = 1;
break;
1019 mm = mh + *mh;
if ( mm[-1] < 0 ) { sign = -1; mm[-1] = -mm[-1]; }
1020 mstop = mm - mm[-1]; m = mh+1; mlength = mm[-1];
1021 while ( tin < t ) *tout++ = *tin++;
1022 while ( m < mstop ) *tout++ = *m++;
1024 while ( tin < tstop ) *tout++ = *tin++;
1025 tlength = REDLENG(tlength);
1026 mlength = REDLENG(mlength);
1027 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)mstop,mlength,
1028 (UWORD *)tout,&newlength) < 0 )
goto CalledFrom;
1029 mlength = INCLENG(newlength);
1030 tout += ABS(mlength);
1031 tout[-1] = mlength*sign;
1032 *termout = tout - termout;
1033 AT.WorkPointer = tout;
1034 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
1042 for ( i = 1; i < numargs; i++ ) {
1043 for ( ii = i; ii > 0; ii-- ) {
1044 if ( abuf[ii-1].size <= abuf[ii].size )
break;
1045 ab = abuf[ii-1]; abuf[ii-1] = abuf[ii]; abuf[ii] = ab;
1053 gcdout = abuf[ii].buffer;
1054 for ( i = 0; i < numargs; i++ ) {
1055 if ( abuf[i].buffer[0] ) { gcdout = abuf[i].buffer; ii = i; i++; argsdone++;
break; }
1057 for ( ; i < numargs; i++ ) {
1058 if ( abuf[i].buffer[0] ) {
1059 g = GCDfunction3(BHEAD gcdout,abuf[i].buffer);
1061 if ( gcdout != abuf[ii].buffer ) M_free(gcdout,
"gcdout");
1063 if ( gcdout[*gcdout] == 0 && gcdout[0] == 4 && gcdout[1] == 1
1064 && gcdout[2] == 1 && gcdout[3] == 3 )
break;
1069 tlength = REDLENG(tlength);
1071 tin = term; tout = termout;
while ( tin < t ) *tout++ = *tin++;
1073 mnext = mm + *mm; mlength = mnext[-1]; mstop = mnext - ABS(mlength);
1075 while ( mm < mstop ) *tout++ = *mm++;
1076 while ( tin < tstop ) *tout++ = *tin++;
1077 mlength = REDLENG(mlength);
1078 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)mm,mlength,
1079 (UWORD *)tout,&newlength) < 0 )
goto CalledFrom;
1080 mlength = INCLENG(newlength);
1081 tout += ABS(mlength);
1083 *termout = tout - termout;
1084 AT.WorkPointer = tout;
1085 if ( argsdone &&
Generator(BHEAD termout,level) < 0 )
goto CalledFrom;
1088 if ( action && ( gcdout != abuf[ii].buffer ) ) M_free(gcdout,
"gcdout");
1095 for ( i = 0; i < numargs; i++ ) {
1096 if ( abuf[i].type == 0 ) { M_free(abuf[i].buffer,
"argbuffer type 0"); }
1097 else if ( abuf[i].type == 1 ) {
1099 if ( d->factors ) M_free(d->factors,
"Dollar factors");
1100 M_free(d,
"Copy of dollar variable");
1102 else if ( abuf[i].type == 2 ) { M_free(abuf[i].buffer,
"CreateExpression"); }
1104 M_free(abuf,
"argbuffer");
1109 AT.pWorkPointer = args;
1110 AT.WorkPointer = termout;
1114 MLOCK(ErrorMessageLock);
1115 MesCall(
"GCDfunction");
1116 MUNLOCK(ErrorMessageLock);
1141WORD *GCDfunction3(PHEAD WORD *in1, WORD *in2)
1144 WORD oldsorttype = AR.SortType, *ow = AT.WorkPointer;;
1145 WORD *t, *tt, *gcdout, *term1, *term2, *confree1, *confree2, *gcdout1, *proper1, *proper2;
1146 int i, actionflag1, actionflag2;
1147 WORD startebuf = cbuf[AT.ebufnum].numrhs;
1148 WORD tryterm1, tryterm2;
1149 if ( in2[*in2] == 0 ) { t = in1; in1 = in2; in2 = t; }
1150 if ( in1[*in1] == 0 ) {
1151 gcdout = (WORD *)Malloc1((*in1+1)*
sizeof(WORD),
"gcdout");
1152 i = *in1; t = gcdout; tt = in1; NCOPY(t,tt,i); *t = 0;
1155 GCDterms(BHEAD gcdout,t,gcdout);
1156 if ( gcdout[0] == 4 && gcdout[1] == 1
1157 && gcdout[2] == 1 && gcdout[3] == 3 )
break;
1160 AT.WorkPointer = ow;
1167 AR.SortType = SORTHIGHFIRST;
1168 term1 = TermMalloc(
"GCDfunction3-a");
1169 term2 = TermMalloc(
"GCDfunction3-b");
1171 tryterm1 = AN.tryterm; AN.tryterm = 0;
1173 tryterm2 = AN.tryterm; AN.tryterm = 0;
1178 GCDterms(BHEAD term1,term2,term1);
1179 TermFree(term2,
"GCDfunction3-b");
1184 if ( ( proper1 = PutExtraSymbols(BHEAD confree1,startebuf,&actionflag1) ) == 0 )
goto CalledFrom;
1185 if ( confree1 != in1 ) {
1186 if ( tryterm1 ) { TermFree(confree1,
"TakeContent"); }
1187 else { M_free(confree1,
"TakeContent"); }
1192 if ( ( proper2 = PutExtraSymbols(BHEAD confree2,startebuf,&actionflag2) ) == 0 )
goto CalledFrom;
1193 if ( confree2 != in2 ) {
1194 if ( tryterm2 ) { TermFree(confree2,
"TakeContent"); }
1195 else { M_free(confree2,
"TakeContent"); }
1203 gcdout1 =
poly_gcd(BHEAD proper1,proper2,0);
1204 M_free(proper1,
"PutExtraSymbols");
1205 M_free(proper2,
"PutExtraSymbols");
1207 AR.SortType = oldsorttype;
1208 if ( actionflag1 || actionflag2 ) {
1209 if ( ( gcdout = TakeExtraSymbols(BHEAD gcdout1,startebuf) ) == 0 )
goto CalledFrom;
1210 M_free(gcdout1,
"gcdout");
1216 cbuf[AT.ebufnum].numrhs = startebuf;
1220 if ( term1[0] != 4 || term1[3] != 3 || term1[1] != 1 || term1[2] != 1 ) {
1222 if ( ( gcdout1 = MultiplyWithTerm(BHEAD gcdout,term1,2) ) == 0 )
goto CalledFrom;
1224 M_free(gcdout,
"gcdout");
1227 TermFree(term1,
"GCDfunction3-a");
1228 AT.WorkPointer = ow;
1232 MLOCK(ErrorMessageLock);
1233 MesCall(
"GCDfunction3");
1234 MUNLOCK(ErrorMessageLock);
1243WORD *PutExtraSymbols(PHEAD WORD *in,WORD startebuf,
int *actionflag)
1245 WORD *termout = AT.WorkPointer;
1254 if ( action > 0 ) *actionflag = 1;
1258 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1261 MLOCK(ErrorMessageLock);
1262 MesCall(
"PutExtraSymbols");
1263 MUNLOCK(ErrorMessageLock);
1272WORD *TakeExtraSymbols(PHEAD WORD *in,WORD startebuf)
1274 CBUF *C = cbuf+AC.cbufnum;
1275 CBUF *CC = cbuf+AT.ebufnum;
1276 WORD *oldworkpointer = AT.WorkPointer, *termout;
1278 termout = AT.WorkPointer;
1281 if ( ConvertFromPoly(BHEAD in,termout,numxsymbol,CC->numrhs-startebuf+numxsymbol,startebuf-numxsymbol,1) <= 0 ) {
1286 AT.WorkPointer = termout + *termout;
1290 if (
Generator(BHEAD termout,C->numlhs) ) {
1295 AT.WorkPointer = oldworkpointer;
1296 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1300 MLOCK(ErrorMessageLock);
1301 MesCall(
"TakeExtraSymbols");
1302 MUNLOCK(ErrorMessageLock);
1311WORD *MultiplyWithTerm(PHEAD WORD *in, WORD *term, WORD par)
1313 WORD *termout, *t, *tt, *tstop, *ttstop;
1314 WORD length, length1, length2;
1315 WORD oldsorttype = AR.SortType;
1316 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
1319 if ( par == 0 || par == 2 ) AR.SortType = SORTHIGHFIRST;
1320 else AR.SortType = SORTLOWFIRST;
1321 termout = AT.WorkPointer;
1325 tstop = in + *in; tstop -= ABS(tstop[-1]); t = in + 1;
1326 while ( t < tstop ) *tt++ = *t++;
1327 ttstop = term + *term; ttstop -= ABS(ttstop[-1]); t = term + 1;
1328 while ( t < ttstop ) *tt++ = *t++;
1329 length1 = REDLENG(in[*in-1]); length2 = REDLENG(term[*term-1]);
1330 if ( MulRat(BHEAD (UWORD *)tstop,length1,
1331 (UWORD *)ttstop,length2,(UWORD *)tt,&length) )
goto CalledFrom;
1332 length = INCLENG(length);
1333 tt += ABS(length); tt[-1] = length;
1334 *termout = tt - termout;
1336 Normalize(BHEAD termout);
1343 if (
EndSort(BHEAD (WORD *)((
void *)(&termout)),2) < 0 )
goto CalledFrom;
1346 if (
EndSort(BHEAD termout,1) < 0 )
goto CalledFrom;
1349 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
1351 AR.SortType = oldsorttype;
1355 MLOCK(ErrorMessageLock);
1356 MesCall(
"MultiplyWithTerm");
1357 MUNLOCK(ErrorMessageLock);
1379 WORD *t, *tstop, *tcom, *tout, *tstore, *r, *rstop, *m, *mm, *w, *ww, *wterm;
1380 WORD *tnext, *tt, *tterm, code[2];
1382 int i, j, k, action = 0, sign;
1383 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMbuffer2, *ap;
1384 WORD GCDlen, GCDlen2, LCMlen, LCMlen2, length, redlength, len1, len2;
1385 tout = tstore = term+1;
1391 tstop = tnext-ABS(tnext[-1]);
1393 while ( t < tstop ) {
1394 if ( *t == INDEX ) {
1395 i = t[1]; NCOPY(tout,t,i);
break;
1399 if ( tout > tstore ) {
1403 rstop = tnext - ABS(tnext[-1]);
1405 if ( r == rstop )
goto noindices;
1406 while ( r < rstop ) {
1407 if ( *r != INDEX ) { r += r[1];
continue; }
1409 while ( m < tout ) {
1410 for ( i = 2; i < r[1]; i++ ) {
1411 if ( *m == r[i] )
break;
1415 while ( mm < tout ) { mm[-1] = mm[0]; mm++; }
1416 tout--; tstore[1]--; m--;
1422 if ( tout <= tstore+2 ) {
1423 tout = tstore;
break;
1427 if ( tout > tstore+2 ) {
1431 tnext = t + *t; t++; w++;
1432 while ( *t != INDEX ) { i = t[1]; NCOPY(w,t,i); }
1433 tt = t + t[1]; t += 2; r = tstore+2; ww = w; *w++ = INDEX; w++;
1434 while ( r < tout && t < tt ) {
1435 if ( *r > *t ) { *w++ = *t++; }
1436 else if ( *r == *t ) { r++; t++; }
1437 else goto CalledFrom;
1439 if ( r < tout )
goto CalledFrom;
1440 while ( t < tt ) *w++ = *t++;
1442 if ( ww[1] == 2 ) w = ww;
1443 while ( t < tnext ) *w++ = *t++;
1455 code[0] = VECTOR; code[1] = DELTA;
1456 for ( k = 0; k < 2; k++ ) {
1459 tstop = tnext-ABS(tnext[-1]);
1461 while ( t < tstop ) {
1462 if ( *t == code[k] ) {
1463 i = t[1]; NCOPY(tout,t,i);
break;
1467 if ( tout > tstore ) {
1471 rstop = tnext - ABS(tnext[-1]);
1473 if ( r == rstop ) { tstore = tout;
goto novectors; }
1474 while ( r < rstop ) {
1475 if ( *r != code[k] ) { r += r[1];
continue; }
1477 while ( m < tout ) {
1478 for ( i = 2; i < r[1]; i += 2 ) {
1479 if ( *m == r[i] && m[1] == r[i+1] )
break;
1483 while ( mm < tout ) { mm[-2] = mm[0]; mm[-1] = mm[1]; mm += 2; }
1484 tout -= 2; tstore[1] -= 2; m -= 2;
1490 if ( tout <= tstore+2 ) {
1491 tout = tstore;
break;
1495 if ( tout > tstore+2 ) {
1499 tnext = t + *t; t++; w++;
1500 while ( *t != code[k] ) { i = t[1]; NCOPY(w,t,i); }
1501 tt = t + t[1]; t += 2; r = tstore+2; ww = w; *w++ = code[k]; w++;
1502 while ( r < tout && t < tt ) {
1503 if ( ( *r > *t ) || ( *r == *t && r[1] > t[1] ) )
1504 { *w++ = *t++; *w++ = *t++; }
1505 else if ( *r == *t && r[1] == t[1] ) { r += 2; t += 2; }
1506 else goto CalledFrom;
1508 if ( r < tout )
goto CalledFrom;
1509 while ( t < tt ) *w++ = *t++;
1511 if ( ww[1] == 2 ) w = ww;
1512 while ( t < tnext ) *w++ = *t++;
1527 tstop = tnext-ABS(tnext[-1]);
1530 while ( t < tstop ) {
1531 if ( *t >= FUNCTION ) {
1532 if ( functions[*t-FUNCTION].commute ) {
1533 if ( tcom == 0 ) { tcom = tout; }
1535 for ( i = 0; i < t[1]; i++ ) {
1536 if ( t[i] != tcom[i] ) {
1537 MLOCK(ErrorMessageLock);
1538 MesPrint(
"GCD or factorization of more than one noncommuting object not allowed");
1539 MUNLOCK(ErrorMessageLock);
1545 i = t[1]; NCOPY(tout,t,i);
1549 if ( tout > tstore ) {
1552 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1553 if ( t == tstop )
goto nofunctions;
1555 while ( r < tout ) {
1557 while ( tt < tstop ) {
1558 for ( i = 0; i < r[1]; i++ ) {
1559 if ( r[i] != tt[i] )
break;
1561 if ( i == r[1] ) { r += r[1];
goto nextr1; }
1567 m = r; mm = r + r[1];
1568 while ( mm < tout ) *m++ = *mm++;
1572 if ( tout <= tstore )
break;
1576 if ( tout > tstore ) {
1582 while ( r < tout ) {
1583 t = in; ww = w = in;
1590 for ( i = 0; i < r[1]; i++ ) {
1591 if ( t[i] != r[i] ) {
1592 j = t[1]; NCOPY(w,t,j);
1598 while ( t < tnext ) *w++ = *t++;
1619 tterm = AT.WorkPointer; tt = tterm+1;
1620 tout[0] = SYMBOL; tout[1] = 2;
1622 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1623 while ( t < tstop ) {
1624 if ( *t == SYMBOL ) {
1625 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
1632 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1638 while ( t < tstop ) {
1639 if ( *t == SYMBOL ) {
1640 MergeSymbolLists(BHEAD tout,t,-1);
1648 if ( tout[1] > 2 ) {
1650 tt[0] = t[0]; tt[1] = t[1];
1651 for ( i = 2; i < t[1]; i += 2 ) {
1652 tt[i] = t[i]; tt[i+1] = -t[i+1];
1667 tout[0] = DOTPRODUCT; tout[1] = 2;
1669 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1670 while ( t < tstop ) {
1671 if ( *t == DOTPRODUCT ) {
1672 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
1679 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
1684 while ( t < tstop ) {
1685 if ( *t == DOTPRODUCT ) {
1686 MergeDotproductLists(BHEAD tout,t,-1);
1693 if ( tout[1] > 2 ) {
1695 tt[0] = t[0]; tt[1] = t[1];
1696 for ( i = 2; i < t[1]; i += 3 ) {
1697 tt[i] = t[i]; tt[i+1] = t[i+1]; tt[i+2] = -t[i+2];
1710 AT.WorkPointer = tt;
1711 if ( AN.cmod != 0 ) {
1713 t = in; tnext = t + *t; tstop = tnext - ABS(tnext[-1]);
1715 if ( tnext[-1] < 0 ) x += AC.cmod[0];
1716 if (
GetModInverses(x,(WORD)(AN.cmod[0]),&ix,&ip) )
goto CalledFrom;
1717 *tout++ = x; *tout++ = 1; *tout++ = 3;
1718 *tt++ = ix; *tt++ = 1; *tt++ = 3;
1721 GCDbuffer = NumberMalloc(
"MakeInteger");
1722 GCDbuffer2 = NumberMalloc(
"MakeInteger");
1723 LCMbuffer = NumberMalloc(
"MakeInteger");
1724 LCMbuffer2 = NumberMalloc(
"MakeInteger");
1726 tnext = t + *t; length = tnext[-1];
1727 if ( length < 0 ) { sign = -1; length = -length; }
1729 tstop = tnext - length;
1730 redlength = (length-1)/2;
1731 for ( i = 0; i < redlength; i++ ) {
1732 GCDbuffer[i] = (UWORD)(tstop[i]);
1733 LCMbuffer[i] = (UWORD)(tstop[redlength+i]);
1735 GCDlen = LCMlen = redlength;
1736 while ( GCDbuffer[GCDlen-1] == 0 ) GCDlen--;
1737 while ( LCMbuffer[LCMlen-1] == 0 ) LCMlen--;
1740 tnext = t + *t; length = ABS(tnext[-1]);
1741 tstop = tnext - length; redlength = (length-1)/2;
1742 len1 = len2 = redlength;
1743 den = tstop + redlength;
1744 while ( tstop[len1-1] == 0 ) len1--;
1745 while ( den[len2-1] == 0 ) len2--;
1746 if ( GCDlen == 1 && GCDbuffer[0] == 1 ) {}
1748 GcdLong(BHEAD (UWORD *)tstop,len1,GCDbuffer,GCDlen,GCDbuffer2,&GCDlen2);
1749 ap = GCDbuffer; GCDbuffer = GCDbuffer2; GCDbuffer2 = ap;
1750 a = GCDlen; GCDlen = GCDlen2; GCDlen2 = a;
1752 if ( len2 == 1 && den[0] == 1 ) {}
1754 GcdLong(BHEAD LCMbuffer,LCMlen,(UWORD *)den,len2,LCMbuffer2,&LCMlen2);
1755 DivLong((UWORD *)den,len2,LCMbuffer2,LCMlen2,
1756 GCDbuffer2,&GCDlen2,(UWORD *)AT.WorkPointer,&a);
1757 MulLong(LCMbuffer,LCMlen,GCDbuffer2,GCDlen2,LCMbuffer2,&LCMlen2);
1758 ap = LCMbuffer; LCMbuffer = LCMbuffer2; LCMbuffer2 = ap;
1759 a = LCMlen; LCMlen = LCMlen2; LCMlen2 = a;
1763 if ( GCDlen != 1 || GCDbuffer[0] != 1 || LCMlen != 1 || LCMbuffer[0] != 1 ) {
1764 redlength = GCDlen;
if ( LCMlen > GCDlen ) redlength = LCMlen;
1765 for ( i = 0; i < GCDlen; i++ ) *tout++ = (WORD)(GCDbuffer[i]);
1766 for ( ; i < redlength; i++ ) *tout++ = 0;
1767 for ( i = 0; i < LCMlen; i++ ) *tout++ = (WORD)(LCMbuffer[i]);
1768 for ( ; i < redlength; i++ ) *tout++ = 0;
1769 *tout++ = (2*redlength+1)*sign;
1770 for ( i = 0; i < LCMlen; i++ ) *tt++ = (WORD)(LCMbuffer[i]);
1771 for ( ; i < redlength; i++ ) *tt++ = 0;
1772 for ( i = 0; i < GCDlen; i++ ) *tt++ = (WORD)(GCDbuffer[i]);
1773 for ( ; i < redlength; i++ ) *tt++ = 0;
1774 *tt++ = (2*redlength+1)*sign;
1778 *tout++ = 1; *tout++ = 1; *tout++ = 3*sign;
1779 *tt++ = 1; *tt++ = 1; *tt++ = 3*sign;
1780 if ( sign != 1 ) action++;
1783 NumberFree(LCMbuffer2,
"MakeInteger");
1784 NumberFree(LCMbuffer ,
"MakeInteger");
1785 NumberFree(GCDbuffer2,
"MakeInteger");
1786 NumberFree(GCDbuffer ,
"MakeInteger");
1793 *tterm = tt - tterm;
1794 AT.WorkPointer = tt;
1795 inp = MultiplyWithTerm(BHEAD in,tterm,2);
1796 AT.WorkPointer = tterm;
1802 *term = tout - term;
1803 AT.WorkPointer = tterm;
1806 MLOCK(ErrorMessageLock);
1807 MesCall(
"TakeContent");
1808 MUNLOCK(ErrorMessageLock);
1824int MergeSymbolLists(PHEAD WORD *old, WORD *extra,
int par)
1827 WORD *
new = TermMalloc(
"MergeSymbolLists");
1828 WORD *t1, *t2, *fill;
1831 i1 = old[1] - 2; i2 = extra[1] - 2;
1832 t1 = old + 2; t2 = extra + 2;
1835 while ( i1 > 0 && i2 > 0 ) {
1837 if ( t2[1] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1841 else if ( *t1 < *t2 ) {
1842 if ( t1[1] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1846 else if ( t1[1] < t2[1] ) {
1847 *fill++ = *t1++; *fill++ = *t1++; t2 += 2;
1851 *fill++ = *t2++; *fill++ = *t2++; t1 += 2;
1855 for ( ; i1 > 0; i1 -= 2 ) {
1856 if ( t1[1] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1859 for ( ; i2 > 0; i2 -= 2 ) {
1860 if ( t2[1] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1865 while ( i1 > 0 && i2 > 0 ) {
1867 if ( t2[1] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1871 else if ( *t1 < *t2 ) {
1872 if ( t1[1] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1876 else if ( t1[1] > t2[1] ) {
1877 *fill++ = *t1++; *fill++ = *t1++; t2 += 2;
1881 *fill++ = *t2++; *fill++ = *t2++; t1 += 2;
1885 for ( ; i1 > 0; i1 -= 2 ) {
1886 if ( t1[1] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; }
1889 for ( ; i2 > 0; i2 -= 2 ) {
1890 if ( t2[1] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; }
1895 while ( i1 > 0 && i2 > 0 ) {
1899 else if ( *t1 < *t2 ) {
1902 else if ( ( t1[1] > 0 ) && ( t2[1] < 0 ) ) { t1 += 2; t2 += 2; i1 -= 2; i2 -= 2; }
1903 else if ( ( t1[1] < 0 ) && ( t2[1] > 0 ) ) { t1 += 2; t2 += 2; i1 -= 2; i2 -= 2; }
1904 else if ( t1[1] > 0 ) {
1905 if ( t1[1] < t2[1] ) {
1906 *fill++ = *t1++; *fill++ = *t1++; t2 += 2; i2 -= 2;
1909 *fill++ = *t2++; *fill++ = *t2++; t1 += 2; i1 -= 2;
1913 if ( t2[1] < t1[1] ) {
1914 *fill++ = *t2++; *fill++ = *t2++; t1 += 2; i1 -= 2; i2 -= 2;
1917 *fill++ = *t1++; *fill++ = *t1++; t2 += 2; i1 -= 2; i2 -= 2;
1921 for ( ; i1 > 0; i1-- ) *fill++ = *t1++;
1922 for ( ; i2 > 0; i2-- ) *fill++ = *t2++;
1926 i1 =
new[1] = fill -
new;
1927 t2 =
new; t1 = old; NCOPY(t1,t2,i1);
1928 TermFree(
new,
"MergeSymbolLists");
1944int MergeDotproductLists(PHEAD WORD *old, WORD *extra,
int par)
1947 WORD *
new = TermMalloc(
"MergeDotproductLists");
1948 WORD *t1, *t2, *fill;
1951 i1 = old[1] - 2; i2 = extra[1] - 2;
1952 t1 = old + 2; t2 = extra + 2;
1955 while ( i1 > 0 && i2 > 0 ) {
1956 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
1957 if ( t2[2] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1961 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
1962 if ( t1[2] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
1966 else if ( t1[2] < t2[2] ) {
1967 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
1971 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
1975 for ( ; i1 > 0; i1 -= 3 ) {
1976 if ( t1[2] < 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
1979 for ( ; i2 > 0; i2 -= 3 ) {
1980 if ( t2[2] < 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1985 while ( i1 > 0 && i2 > 0 ) {
1986 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
1987 if ( t2[2] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
1991 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
1992 if ( t1[2] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
1996 else if ( t1[2] > t2[2] ) {
1997 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2001 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2005 for ( ; i1 > 0; i1 -= 3 ) {
2006 if ( t1[2] > 0 ) { *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; }
2009 for ( ; i2 > 0; i2 -= 3 ) {
2010 if ( t2[2] > 0 ) { *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; }
2015 while ( i1 > 0 && i2 > 0 ) {
2016 if ( ( *t1 > *t2 ) || ( *t1 == *t2 && t1[1] > t2[1] ) ) {
2020 else if ( ( *t1 < *t2 ) || ( *t1 == *t2 && t1[1] < t2[1] ) ) {
2024 else if ( ( t1[2] > 0 ) && ( t2[2] < 0 ) ) { t1 += 3; t2 += 3; i1 -= 3; i2 -= 3; }
2025 else if ( ( t1[2] < 0 ) && ( t2[2] > 0 ) ) { t1 += 3; t2 += 3; i1 -= 3; i2 -= 3; }
2026 else if ( t1[2] > 0 ) {
2027 if ( t1[2] < t2[2] ) {
2028 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2032 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2038 if ( t2[2] < t1[2] ) {
2039 *fill++ = *t2++; *fill++ = *t2++; *fill++ = *t2++; t1 += 3;
2043 *fill++ = *t1++; *fill++ = *t1++; *fill++ = *t1++; t2 += 3;
2048 for ( ; i1 > 0; i1-- ) *fill++ = *t1++;
2049 for ( ; i2 > 0; i2-- ) *fill++ = *t2++;
2052 new[0] = DOTPRODUCT;
2053 i1 =
new[1] = fill -
new;
2054 t2 =
new; t1 = old; NCOPY(t1,t2,i1);
2055 TermFree(
new,
"MergeDotproductLists");
2071WORD *CreateExpression(PHEAD WORD nexp)
2074 CBUF *C = cbuf+AC.cbufnum;
2075 POSITION startposition, oldposition;
2077 WORD *term, *oldipointer = AR.CompressPointer;
2079 switch ( Expressions[nexp].status ) {
2080 case HIDDENLEXPRESSION:
2081 case HIDDENGEXPRESSION:
2082 case DROPHLEXPRESSION:
2083 case DROPHGEXPRESSION:
2084 case UNHIDELEXPRESSION:
2085 case UNHIDEGEXPRESSION:
2086 AR.GetOneFile = 2; fi = AR.hidefile;
2089 AR.GetOneFile = 0; fi = AR.infile;
2092 SeekScratch(fi,&oldposition);
2093 startposition = AS.OldOnFile[nexp];
2094 term = AT.WorkPointer;
2095 if ( GetOneTerm(BHEAD term,fi,&startposition,0) <= 0 )
goto CalledFrom;
2097 AR.CompressPointer = oldipointer;
2098 while ( GetOneTerm(BHEAD term,fi,&startposition,0) > 0 ) {
2099 AT.WorkPointer = term + *term;
2100 if (
Generator(BHEAD term,C->numlhs) ) {
2104 AR.CompressPointer = oldipointer;
2106 AT.WorkPointer = term;
2107 if (
EndSort(BHEAD (WORD *)((
void *)(&term)),2) < 0 )
goto CalledFrom;
2108 SetScratch(fi,&oldposition);
2111 MLOCK(ErrorMessageLock);
2112 MesCall(
"CreateExpression");
2113 MUNLOCK(ErrorMessageLock);
2127int GCDterms(PHEAD WORD *term1, WORD *term2, WORD *termout)
2130 WORD *t1, *t1stop, *t1next, *t2, *t2stop, *t2next, *tout, *tt1, *tt2;
2131 int count1, count2, i, ii, x1, sign;
2132 WORD length1, length2;
2133 t1 = term1 + *term1; t1stop = t1 - ABS(t1[-1]); t1 = term1+1;
2134 t2 = term2 + *term2; t2stop = t2 - ABS(t2[-1]); t2 = term2+1;
2136 while ( t1 < t1stop ) {
2137 t1next = t1 + t1[1];
2139 if ( *t1 == SYMBOL ) {
2140 while ( t2 < t2stop && *t2 != SYMBOL ) t2 += t2[1];
2141 if ( t2 < t2stop && *t2 == SYMBOL ) {
2143 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2144 while ( tt1 < t1next && tt2 < t2next ) {
2145 if ( *tt1 < *tt2 ) tt1 += 2;
2146 else if ( *tt1 > *tt2 ) tt2 += 2;
2147 else if ( ( tt1[1] > 0 && tt2[1] < 0 ) ||
2148 ( tt2[1] > 0 && tt1[1] < 0 ) ) {
2153 if ( tt1[1] < 0 ) {
if ( tt2[1] > x1 ) x1 = tt2[1]; }
2154 else {
if ( tt2[1] < x1 ) x1 = tt2[1]; }
2155 tout[count1+2] = *tt1;
2156 tout[count1+3] = x1;
2162 *tout = SYMBOL; tout[1] = count1+2; tout += tout[1];
2166 else if ( *t1 == DOTPRODUCT ) {
2167 while ( t2 < t2stop && *t2 != DOTPRODUCT ) t2 += t2[1];
2168 if ( t2 < t2stop && *t2 == DOTPRODUCT ) {
2170 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2171 while ( tt1 < t1next && tt2 < t2next ) {
2172 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 3;
2173 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 3;
2174 else if ( ( tt1[2] > 0 && tt2[2] < 0 ) ||
2175 ( tt2[2] > 0 && tt1[2] < 0 ) ) {
2180 if ( tt1[2] < 0 ) {
if ( tt2[2] > x1 ) x1 = tt2[2]; }
2181 else {
if ( tt2[2] < x1 ) x1 = tt2[2]; }
2182 tout[count1+2] = *tt1;
2183 tout[count1+3] = tt1[1];
2184 tout[count1+4] = x1;
2190 *tout = DOTPRODUCT; tout[1] = count1+2; tout += tout[1];
2194 else if ( *t1 == VECTOR ) {
2195 while ( t2 < t2stop && *t2 != VECTOR ) t2 += t2[1];
2196 if ( t2 < t2stop && *t2 == VECTOR ) {
2198 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2199 while ( tt1 < t1next && tt2 < t2next ) {
2200 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 2;
2201 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 2;
2203 tout[count1+2] = *tt1;
2204 tout[count1+3] = tt1[1];
2210 *tout = VECTOR; tout[1] = count1+2; tout += tout[1];
2214 else if ( *t1 == INDEX ) {
2215 while ( t2 < t2stop && *t2 != INDEX ) t2 += t2[1];
2216 if ( t2 < t2stop && *t2 == INDEX ) {
2218 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2219 while ( tt1 < t1next && tt2 < t2next ) {
2220 if ( *tt1 < *tt2 ) tt1 += 1;
2221 else if ( *tt1 > *tt2 ) tt2 += 1;
2223 tout[count1+2] = *tt1;
2229 *tout = INDEX; tout[1] = count1+2; tout += tout[1];
2233 else if ( *t1 == DELTA ) {
2234 while ( t2 < t2stop && *t2 != DELTA ) t2 += t2[1];
2235 if ( t2 < t2stop && *t2 == DELTA ) {
2237 tt1 = t1+2; tt2 = t2+2; count1 = 0;
2238 while ( tt1 < t1next && tt2 < t2next ) {
2239 if ( *tt1 < *tt2 || ( *tt1 == *tt2 && tt1[1] < tt2[1] ) ) tt1 += 2;
2240 else if ( *tt1 > *tt2 || ( *tt1 == *tt2 && tt1[1] > tt2[1] ) ) tt2 += 2;
2242 tout[count1+2] = *tt1;
2243 tout[count1+3] = tt1[1];
2249 *tout = DELTA; tout[1] = count1+2; tout += tout[1];
2253 else if ( *t1 >= FUNCTION ) {
2259 while ( t1next < t1stop && *t1 == *t1next && t1[1] == t1next[1] ) {
2260 for ( i = 2; i < t1[1]; i++ ) {
2261 if ( t1[i] != t1next[i] )
break;
2263 if ( i < t1[1] )
break;
2265 t1next += t1next[1];
2268 while ( t2 < t2stop ) {
2269 if ( *t2 == *t1 && t2[1] == t1[1] ) {
2270 for ( i = 2; i < t1[1]; i++ ) {
2271 if ( t2[i] != t1[i] )
break;
2273 if ( i >= t1[1] ) count2++;
2277 if ( count1 < count2 ) count2 = count1;
2280 while ( count2 > 0 ) { tout += tout[1]; count2--; }
2294 length1 = term1[*term1-1]; ii = i = ABS(length1); t1 = t1stop;
2295 if ( t1 != tout ) { NCOPY(tout,t1,i); tout -= ii; }
2296 length2 = term2[*term2-1];
2297 if ( length1 < 0 && length2 < 0 ) sign = -1;
2298 if ( AccumGCD(BHEAD (UWORD *)tout,&length1,(UWORD *)t2stop,length2) ) {
2299 MLOCK(ErrorMessageLock);
2300 MesCall(
"GCDterms");
2301 MUNLOCK(ErrorMessageLock);
2304 if ( sign < 0 && length1 > 0 ) length1 = -length1;
2305 tout += ABS(length1); tout[-1] = length1;
2306 *termout = tout - termout; *tout = 0;
2315int ReadPolyRatFun(PHEAD WORD *term)
2317 WORD *oldworkpointer = AT.WorkPointer;
2319 WORD *t, *fun, *nextt, *num, *den, *t1, *t2, size, numsize, densize;
2320 WORD *term1, *term2, *confree1, *confree2, *gcd, *num1, *den1, move, *newnum, *newden;
2321 WORD *tstop, *m1, *m2;
2322 WORD oldsorttype = AR.SortType;
2323 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
2324 AR.SortType = SORTHIGHFIRST;
2327 tstop = term + *term; tstop -= ABS(tstop[-1]);
2328 if ( term + *term == AT.WorkPointer ) flag = 1;
2331 while ( t < tstop ) {
2332 if ( *t != AR.PolyFun ) { t += t[1];
continue; }
2333 if ( ( t[2] & MUSTCLEANPRF ) == 0 ) { t += t[1];
continue; }
2336 if ( fun[1] > FUNHEAD && fun[FUNHEAD] == -SNUMBER && fun[FUNHEAD+1] == 0 )
2337 { *term = 0;
break; }
2338 if ( FromPolyRatFun(BHEAD fun, &num, &den) > 0 ) { t = nextt;
continue; }
2339 if ( *num == ARGHEAD ) { *term = 0;
break; }
2346 term1 = TermMalloc(
"ReadPolyRatFun");
2347 term2 = TermMalloc(
"ReadPolyRatFun");
2350 GCDclean(BHEAD term1,term2);
2352 gcd =
poly_gcd(BHEAD confree1,confree2,1);
2353 newnum = PolyDiv(BHEAD confree1,gcd,
"ReadPolyRatFun");
2354 newden = PolyDiv(BHEAD confree2,gcd,
"ReadPolyRatFun");
2355 TermFree(confree2,
"ReadPolyRatFun");
2356 TermFree(confree1,
"ReadPolyRatFun");
2357 num1 = MULfunc(BHEAD term1,newnum);
2358 den1 = MULfunc(BHEAD term2,newden);
2359 TermFree(newnum,
"ReadPolyRatFun");
2360 TermFree(newden,
"ReadPolyRatFun");
2362 TermFree(gcd,
"poly_gcd");
2363 TermFree(term1,
"ReadPolyRatFun");
2364 TermFree(term2,
"ReadPolyRatFun");
2371 if ( num1[0] == 4 && num1[4] == 0 && num1[2] == 1 && num1[1] > 0 ) {
2372 numsize = 2; num1[0] = -SNUMBER;
2373 if ( num1[3] < 0 ) num1[1] = -num1[1];
2375 else if ( num1[0] == 8 && num1[8] == 0 && num1[7] == 3 && num1[6] == 1
2376 && num1[5] == 1 && num1[1] == SYMBOL && num1[4] == 1 ) {
2377 numsize = 2; num1[0] = -SYMBOL; num1[1] = num1[3];
2379 else { m1 = num1;
while ( *m1 ) m1 += *m1; numsize = (m1-num1)+ARGHEAD; }
2380 if ( den1[0] == 4 && den1[4] == 0 && den1[2] == 1 && den1[1] > 0 ) {
2381 densize = 2; den1[0] = -SNUMBER;
2382 if ( den1[3] < 0 ) den1[1] = -den1[1];
2384 else if ( den1[0] == 8 && den1[8] == 0 && den1[7] == 3 && den1[6] == 1
2385 && den1[5] == 1 && den1[1] == SYMBOL && den1[4] == 1 ) {
2386 densize = 2; den1[0] = -SYMBOL; den1[1] = den1[3];
2388 else { m2 = den1;
while ( *m2 ) m2 += *m2; densize = (m2-den1)+ARGHEAD; }
2389 size = FUNHEAD+numsize+densize;
2391 if ( size > fun[1] ) {
2392 move = size - fun[1];
2393 t1 = term+*term; t2 = t1+move;
2394 while ( t1 > nextt ) *--t2 = *--t1;
2395 tstop += move; nextt += move;
2398 else if ( size < fun[1] ) {
2400 t2 = fun+size; t1 = nextt;
2401 tstop -= move; nextt -= move;
2403 while ( t1 < t ) *t2++ = *t1++;
2407 fun[1] = size; fun[2] = 0;
2408 t2 = fun+FUNHEAD; t1 = num1;
2409 if ( *num1 < 0 ) { *t2++ = num1[0]; *t2++ = num1[1]; }
2410 else { *t2++ = numsize; *t2++ = 0; FILLARG(t2);
2411 i = numsize-ARGHEAD; NCOPY(t2,t1,i) }
2413 if ( *den1 < 0 ) { *t2++ = den1[0]; *t2++ = den1[1]; }
2414 else { *t2++ = densize; *t2++ = 0; FILLARG(t2);
2415 i = densize-ARGHEAD; NCOPY(t2,t1,i) }
2417 TermFree(num1,
"MULfunc");
2418 TermFree(den1,
"MULfunc");
2422 if ( flag ) AT.WorkPointer = term +*term;
2423 else AT.WorkPointer = oldworkpointer;
2424 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
2425 AR.SortType = oldsorttype;
2434int FromPolyRatFun(PHEAD WORD *fun, WORD **numout, WORD **denout)
2436 WORD *nextfun, *tt, *num, *den;
2438 nextfun = fun + fun[1];
2440 num = AT.WorkPointer;
2442 if ( *fun != -SNUMBER && *fun != -SYMBOL )
goto Improper;
2443 ToGeneral(fun,num,0);
2444 tt = num + *num; *tt++ = 0;
2447 else { i = *fun; tt = num; NCOPY(tt,fun,i); *tt++ = 0; }
2450 if ( *fun != -SNUMBER && *fun != -SYMBOL )
goto Improper;
2451 ToGeneral(fun,den,0);
2452 tt = den + *den; *tt++ = 0;
2455 else { i = *fun; tt = den; NCOPY(tt,fun,i); *tt++ = 0; }
2456 *numout = num; *denout = den;
2457 if ( fun != nextfun ) {
return(1); }
2458 AT.WorkPointer = tt;
2461 MLOCK(ErrorMessageLock);
2462 MesPrint(
"Improper use of PolyRatFun");
2463 MesCall(
"FromPolyRatFun");
2464 MUNLOCK(ErrorMessageLock);
2488 WORD *t, *tstop, *tout, *tstore;
2489 WORD *tnext, *tt, *tterm;
2490 WORD *inp, a, *den, *oldworkpointer = AT.WorkPointer;
2491 int i, action = 0, sign, first;
2492 UWORD *GCDbuffer, *GCDbuffer2, *LCMbuffer, *LCMbuffer2, *ap;
2493 WORD GCDlen, GCDlen2, LCMlen, LCMlen2, length, redlength, len1, len2;
2495 tout = tstore = term+1;
2504 tterm = AT.WorkPointer; tt = tterm+1;
2505 tout[0] = SYMBOL; tout[1] = 2;
2508 tnext = t + *t; tstop = tnext - ABS(tnext[-1]); t++;
2509 while ( t < tstop ) {
2511 if ( *t == SYMBOL ) {
2512 for ( i = 0; i < t[1]; i++ ) tout[i] = t[i];
2516 MLOCK(ErrorMessageLock);
2517 MesPrint ((
char*)
"ERROR: polynomials and polyratfuns must contain symbols only");
2518 MUNLOCK(ErrorMessageLock);
2522 else if ( *t == SYMBOL ) {
2523 MergeSymbolLists(BHEAD tout,t,-1);
2535 for ( i = 2; i < tout[1]; i += 2 ) {
2536 if ( tout[i+1] < 0 ) {
2537 if ( i == j ) { j += 2; }
2538 else { tout[j] = tout[i]; tout[j+1] = tout[i+1]; j += 2; }
2547 if ( tout[1] > 2 ) {
2549 tt[0] = t[0]; tt[1] = t[1];
2550 for ( i = 2; i < t[1]; i += 2 ) {
2551 tt[i] = t[i]; tt[i+1] = -t[i+1];
2564 AT.WorkPointer = tt;
2565 if ( AN.cmod != 0 ) {
2567 t = in; tnext = t + *t; tstop = tnext - ABS(tnext[-1]);
2569 if ( tnext[-1] < 0 ) x += AC.cmod[0];
2570 if (
GetModInverses(x,(WORD)(AN.cmod[0]),&ix,&ip) )
goto CalledFrom;
2571 *tout++ = x; *tout++ = 1; *tout++ = 3;
2572 *tt++ = ix; *tt++ = 1; *tt++ = 3;
2575 GCDbuffer = NumberMalloc(
"MakeInteger");
2576 GCDbuffer2 = NumberMalloc(
"MakeInteger");
2577 LCMbuffer = NumberMalloc(
"MakeInteger");
2578 LCMbuffer2 = NumberMalloc(
"MakeInteger");
2580 tnext = t + *t; length = tnext[-1];
2581 if ( length < 0 ) { sign = -1; length = -length; }
2583 tstop = tnext - length;
2584 redlength = (length-1)/2;
2585 for ( i = 0; i < redlength; i++ ) {
2586 GCDbuffer[i] = (UWORD)(tstop[i]);
2587 LCMbuffer[i] = (UWORD)(tstop[redlength+i]);
2589 GCDlen = LCMlen = redlength;
2590 while ( GCDbuffer[GCDlen-1] == 0 ) GCDlen--;
2591 while ( LCMbuffer[LCMlen-1] == 0 ) LCMlen--;
2594 tnext = t + *t; length = ABS(tnext[-1]);
2595 tstop = tnext - length; redlength = (length-1)/2;
2596 len1 = len2 = redlength;
2597 den = tstop + redlength;
2598 while ( tstop[len1-1] == 0 ) len1--;
2599 while ( den[len2-1] == 0 ) len2--;
2600 if ( GCDlen == 1 && GCDbuffer[0] == 1 ) {}
2602 GcdLong(BHEAD (UWORD *)tstop,len1,GCDbuffer,GCDlen,GCDbuffer2,&GCDlen2);
2603 ap = GCDbuffer; GCDbuffer = GCDbuffer2; GCDbuffer2 = ap;
2604 a = GCDlen; GCDlen = GCDlen2; GCDlen2 = a;
2606 if ( len2 == 1 && den[0] == 1 ) {}
2608 GcdLong(BHEAD LCMbuffer,LCMlen,(UWORD *)den,len2,LCMbuffer2,&LCMlen2);
2609 DivLong((UWORD *)den,len2,LCMbuffer2,LCMlen2,
2610 GCDbuffer2,&GCDlen2,(UWORD *)AT.WorkPointer,&a);
2611 MulLong(LCMbuffer,LCMlen,GCDbuffer2,GCDlen2,LCMbuffer2,&LCMlen2);
2612 ap = LCMbuffer; LCMbuffer = LCMbuffer2; LCMbuffer2 = ap;
2613 a = LCMlen; LCMlen = LCMlen2; LCMlen2 = a;
2617 if ( GCDlen != 1 || GCDbuffer[0] != 1 || LCMlen != 1 || LCMbuffer[0] != 1 ) {
2618 redlength = GCDlen;
if ( LCMlen > GCDlen ) redlength = LCMlen;
2619 for ( i = 0; i < GCDlen; i++ ) *tout++ = (WORD)(GCDbuffer[i]);
2620 for ( ; i < redlength; i++ ) *tout++ = 0;
2621 for ( i = 0; i < LCMlen; i++ ) *tout++ = (WORD)(LCMbuffer[i]);
2622 for ( ; i < redlength; i++ ) *tout++ = 0;
2623 *tout++ = (2*redlength+1)*sign;
2624 for ( i = 0; i < LCMlen; i++ ) *tt++ = (WORD)(LCMbuffer[i]);
2625 for ( ; i < redlength; i++ ) *tt++ = 0;
2626 for ( i = 0; i < GCDlen; i++ ) *tt++ = (WORD)(GCDbuffer[i]);
2627 for ( ; i < redlength; i++ ) *tt++ = 0;
2628 *tt++ = (2*redlength+1)*sign;
2632 *tout++ = 1; *tout++ = 1; *tout++ = 3*sign;
2633 *tt++ = 1; *tt++ = 1; *tt++ = 3*sign;
2634 if ( sign != 1 ) action++;
2636 NumberFree(LCMbuffer2,
"MakeInteger");
2637 NumberFree(LCMbuffer ,
"MakeInteger");
2638 NumberFree(GCDbuffer2,
"MakeInteger");
2639 NumberFree(GCDbuffer ,
"MakeInteger");
2646 *term = tout - term; *tout = 0;
2647 *tterm = tt - tterm; *tt = 0;
2648 AT.WorkPointer = tt;
2649 inp = MultiplyWithTerm(BHEAD in,tterm,2);
2650 AT.WorkPointer = tterm;
2651 t = inp;
while ( *t ) t += *t;
2652 j = (t-inp); t = inp;
2653 if ( j*
sizeof(WORD) > (size_t)(AM.MaxTer) )
goto OverWork;
2654 in = tout = TermMalloc(
"TakeSymbolContent");
2655 NCOPY(tout,t,j); *tout = 0;
2656 if ( AN.tryterm > 0 ) { TermFree(inp,
"MultiplyWithTerm"); AN.tryterm = 0; }
2657 else { M_free(inp,
"MultiplyWithTerm"); }
2660 t = in;
while ( *t ) t += *t;
2662 if ( j*
sizeof(WORD) > (size_t)(AM.MaxTer) )
goto OverWork;
2663 in = tout = TermMalloc(
"TakeSymbolContent");
2664 NCOPY(tout,t,j); *tout = 0;
2665 term[0] = 4; term[1] = 1; term[2] = 1; term[3] = 3; term[4] = 0;
2671 AT.WorkPointer = oldworkpointer;
2675 MLOCK(ErrorMessageLock);
2676 MesPrint(
"Term too complex. Maybe increasing MaxTermSize can help");
2677 MUNLOCK(ErrorMessageLock);
2679 MLOCK(ErrorMessageLock);
2680 MesCall(
"TakeSymbolContent");
2681 MUNLOCK(ErrorMessageLock);
2695void GCDclean(PHEAD WORD *num, WORD *den)
2697 WORD *out1 = TermMalloc(
"GCDclean");
2698 WORD *out2 = TermMalloc(
"GCDclean");
2699 WORD *t1, *t2, *r1, *r2, *t1stop, *t2stop, csize1, csize2, csize3, pow, sign;
2701 t1stop = num+*num; sign = ( t1stop[-1] < 0 ) ? -1 : 1;
2702 csize1 = ABS(t1stop[-1]); t1stop -= csize1;
2703 t2stop = den+*den;
if ( t2stop[-1] < 0 ) sign = -sign;
2704 csize2 = ABS(t2stop[-1]); t2stop -= csize2;
2705 t1 = num+1; t2 = den+1;
2706 r1 = out1+3; r2 = out2+3;
2707 if ( t1 == t1stop ) {
2708 if ( t2 < t2stop ) {
2709 for ( i = 2; i < t2[1]; i += 2 ) {
2710 if ( t2[i+1] < 0 ) { *r1++ = t2[i]; *r1++ = -t2[i+1]; }
2711 else { *r2++ = t2[i]; *r2++ = t2[i+1]; }
2715 else if ( t2 == t2stop ) {
2716 for ( i = 2; i < t1[1]; i += 2 ) {
2717 if ( t1[i+1] < 0 ) { *r2++ = t1[i]; *r2++ = -t1[i+1]; }
2718 else { *r1++ = t1[i]; *r1++ = t1[i+1]; }
2723 while ( t1 < t1stop && t2 < t2stop ) {
2725 if ( t1[1] > 0 ) { *r1++ = *t1; *r1++ = t1[1]; t1 += 2; }
2726 else if ( t1[1] < 0 ) { *r2++ = *t1; *r2++ = -t1[1]; t1 += 2; }
2728 else if ( *t1 > *t2 ) {
2729 if ( t2[1] > 0 ) { *r2++ = *t2; *r2++ = t2[1]; t2 += 2; }
2730 else if ( t2[1] < 0 ) { *r1++ = *t2; *r1++ = -t2[1]; t2 += 2; }
2734 if ( pow > 0 ) { *r1++ = *t1; *r1++ = pow; }
2735 else if ( pow < 0 ) { *r2++ = *t1; *r2++ = -pow; }
2739 while ( t1 < t1stop ) {
2740 if ( t1[1] < 0 ) { *r2++ = *t1; *r2++ = -t1[1]; }
2741 else { *r1++ = *t1; *r1++ = t1[1]; }
2744 while ( t2 < t2stop ) {
2745 if ( t2[1] < 0 ) { *r1++ = *t2; *r1++ = -t2[1]; }
2746 else { *r2++ = *t2; *r2++ = t2[1]; }
2750 if ( r1 > out1+3 ) { out1[1] = SYMBOL; out1[2] = r1 - out1 - 1; }
2752 if ( r2 > out2+3 ) { out2[1] = SYMBOL; out2[2] = r2 - out2 - 1; }
2757 csize1 = REDLENG(csize1);
2758 csize2 = REDLENG(csize2);
2759 if ( DivRat(BHEAD (UWORD *)t1stop,csize1,(UWORD *)t2stop,csize2,(UWORD *)r1,&csize3) ) {
2760 MLOCK(ErrorMessageLock);
2761 MesCall(
"GCDclean");
2762 MUNLOCK(ErrorMessageLock);
2765 UnPack((UWORD *)r1,csize3,&csize2,&csize1);
2766 t2 = r1+ABS(csize3);
2767 for ( i = 0; i < csize2; i++ ) r2[i] = t2[i];
2768 r2 += csize2; *r2++ = 1;
2769 for ( i = 1; i < csize2; i++ ) *r2++ = 0;
2770 csize2 = INCLENG(csize2); *r2++ = csize2; *out2 = r2-out2;
2771 r1 += ABS(csize1); *r1++ = 1;
2772 for ( i = 1; i < ABS(csize1); i++ ) *r1++ = 0;
2773 csize1 = INCLENG(csize1); *r1++ = csize1; *out1 = r1-out1;
2775 t1 = num; t2 = out1; i = *out1; NCOPY(t1,t2,i); *t1 = 0;
2776 if ( sign < 0 ) t1[-1] = -t1[-1];
2777 t1 = den; t2 = out2; i = *out2; NCOPY(t1,t2,i); *t1 = 0;
2779 TermFree(out2,
"GCDclean");
2780 TermFree(out1,
"GCDclean");
2792WORD *PolyDiv(PHEAD WORD *a,WORD *b,
char *text)
2798 return(poly_div(BHEAD a,b,1));
2837WORD divrem[4] = { DIVFUNCTION, REMFUNCTION, INVERSEFUNCTION, MULFUNCTION };
2839int DIVfunction(PHEAD WORD *term,WORD level,
int par)
2842 WORD *t, *tt, *r, *arg1 = 0, *arg2 = 0, *arg3 = 0, *termout;
2843 WORD *tstop, *tend, *r3, *rr, *rstop, tlength, rlength, newlength;
2844 WORD *proper1, *proper2, *proper3 = 0, numdol = -1;
2845 int numargs = 0, type1, type2, actionflag1, actionflag2;
2846 WORD startebuf = cbuf[AT.ebufnum].numrhs;
2847 int division = ( par <= 2 );
2848 if ( par < 0 || par > 3 ) {
2849 MLOCK(ErrorMessageLock);
2850 MesPrint(
"Internal error. Illegal parameter %d in DIVfunction.",par);
2851 MUNLOCK(ErrorMessageLock);
2857 tend = term + *term; tstop = tend - ABS(tend[-1]);
2859 while ( t < tstop ) {
2860 if ( *t != divrem[par] ) { t += t[1];
continue; }
2862 tt = t + t[1]; numargs = 0;
2864 if ( numargs == 0 ) { arg1 = r; }
2865 if ( numargs == 1 ) { arg2 = r; }
2866 if ( numargs == 2 && *r == -DOLLAREXPRESSION ) { numdol = r[1]; }
2870 if ( numargs == 2 )
break;
2871 if ( division && numargs == 3 )
break;
2875 MLOCK(ErrorMessageLock);
2876 MesPrint(
"Internal error. Indicated div_ or rem_ function not encountered.");
2877 MUNLOCK(ErrorMessageLock);
2883 if ( division && *arg1 == -SNUMBER && arg1[1] == 0 ) {
2884 if ( *arg2 == -SNUMBER && arg2[1] == 0 ) {
2886 MLOCK(ErrorMessageLock);
2887 MesPrint(
"0/0 in either div_ or rem_ function.");
2888 MUNLOCK(ErrorMessageLock);
2891 if ( numdol >= 0 ) PutTermInDollar(0,numdol);
2894 if ( division && *arg2 == -SNUMBER && arg2[1] == 0 ) {
2896 MLOCK(ErrorMessageLock);
2897 MesPrint(
"Division by zero in either div_ or rem_ function.");
2898 MUNLOCK(ErrorMessageLock);
2902 if ( (*arg1 == -SNUMBER && arg1[1] == 0) ||
2903 (*arg2 == -SNUMBER && arg2[1] == 0) ) {
2907 if ( ( arg1 = ConvertArgument(BHEAD arg1, &type1) ) == 0 )
goto CalledFrom;
2908 if ( ( arg2 = ConvertArgument(BHEAD arg2, &type2) ) == 0 )
goto CalledFrom;
2909 if ( division && *arg1 == 0 ) {
2911 M_free(arg2,
"DIVfunction");
2912 M_free(arg1,
"DIVfunction");
2915 M_free(arg2,
"DIVfunction");
2916 M_free(arg1,
"DIVfunction");
2917 if ( numdol >= 0 ) PutTermInDollar(0,numdol);
2920 if ( division && *arg2 == 0 ) {
2921 M_free(arg2,
"DIVfunction");
2922 M_free(arg1,
"DIVfunction");
2925 if ( !division && (*arg1 == 0 || *arg2 == 0) ) {
2926 M_free(arg2,
"DIVfunction");
2927 M_free(arg1,
"DIVfunction");
2930 if ( ( proper1 = PutExtraSymbols(BHEAD arg1,startebuf,&actionflag1) ) == 0 )
goto CalledFrom;
2931 if ( ( proper2 = PutExtraSymbols(BHEAD arg2,startebuf,&actionflag2) ) == 0 )
goto CalledFrom;
2940 M_free(arg2,
"DIVfunction");
2949 M_free(arg1,
"DIVfunction");
2950 if ( par == 0 ) proper3 = poly_div(BHEAD proper1, proper2,0);
2951 else if ( par == 1 ) proper3 = poly_rem(BHEAD proper1, proper2,0);
2952 else if ( par == 2 ) proper3 = poly_inverse(BHEAD proper1, proper2);
2953 else if ( par == 3 ) proper3 = poly_mul(BHEAD proper1, proper2);
2954 if ( proper3 == 0 )
goto CalledFrom;
2955 if ( actionflag1 || actionflag2 ) {
2956 if ( ( arg3 = TakeExtraSymbols(BHEAD proper3,startebuf) ) == 0 )
goto CalledFrom;
2957 M_free(proper3,
"DIVfunction");
2962 M_free(proper2,
"DIVfunction");
2963 M_free(proper1,
"DIVfunction");
2964 cbuf[AT.ebufnum].numrhs = startebuf;
2966 termout = AT.WorkPointer;
2968 tlength = REDLENG(tlength);
2971 tt = term + 1; rr = termout + 1;
2972 while ( tt < t ) *rr++ = *tt++;
2975 rstop = r3 - ABS(r3[-1]);
2976 while ( r < rstop ) *rr++ = *r++;
2978 while ( tt < tstop ) *rr++ = *tt++;
2980 rlength = REDLENG(rlength);
2981 if ( MulRat(BHEAD (UWORD *)tstop,tlength,(UWORD *)rstop,rlength,
2982 (UWORD *)rr,&newlength) < 0 )
goto CalledFrom;
2983 rlength = INCLENG(newlength);
2986 *termout = rr - termout;
2987 AT.WorkPointer = rr;
2988 if (
Generator(BHEAD termout,level) )
goto CalledFrom;
2990 AT.WorkPointer = termout;
2992 M_free(arg3,
"DIVfunction");
2995 MLOCK(ErrorMessageLock);
2996 MesCall(
"DIVfunction");
2997 MUNLOCK(ErrorMessageLock);
3008WORD *MULfunc(PHEAD WORD *p1, WORD *p2)
3010 WORD *prod,size1,size2,size3,*t,*tfill,*ps1,*ps2,sign1,sign2, error, *p3;
3011 UWORD *num1, *num2, *num3;
3013 WORD oldsorttype = AR.SortType;
3014 COMPARE oldcompareroutine = (COMPARE)(AR.CompareRoutine);
3015 AR.SortType = SORTHIGHFIRST;
3017 num3 = NumberMalloc(
"MULfunc");
3018 prod = TermMalloc(
"MULfunc");
3021 ps1 = p1+*p1; num1 = (UWORD *)(ps1 - ABS(ps1[-1])); size1 = ps1[-1];
3022 if ( size1 < 0 ) { sign1 = -1; size1 = -size1; }
3024 size1 = (size1-1)/2;
3027 ps2 = p3+*p3; num2 = (UWORD *)(ps2 - ABS(ps2[-1])); size2 = ps2[-1];
3028 if ( size2 < 0 ) { sign2 = -1; size2 = -size2; }
3030 size2 = (size2-1)/2;
3031 if ( MulLong(num1,size1,num2,size2,num3,&size3) ) {
3034 MLOCK(ErrorMessageLock);
3035 MesPrint(
" Error %d",error);
3037 MUNLOCK(ErrorMessageLock);
3041 t = p1+1;
while ( t < (WORD *)num1 ) *tfill++ = *t++;
3042 t = p3+1;
while ( t < (WORD *)num2 ) *tfill++ = *t++;
3044 for ( i = 0; i < size3; i++ ) *tfill++ = *t++;
3046 for ( i = 1; i < size3; i++ ) *tfill++ = 0;
3047 *tfill++ = (2*size3+1)*sign1*sign2;
3048 prod[0] = tfill - prod;
3050 if (
StoreTerm(BHEAD prod) ) { error = 3;
goto CalledFrom; }
3055 NumberFree(num3,
"MULfunc");
3057 AR.CompareRoutine = (COMPAREDUMMY)oldcompareroutine;
3058 AR.SortType = oldsorttype;
3069WORD *ConvertArgument(PHEAD WORD *arg,
int *type)
3071 WORD *output, *t, *r;
3074 output = (WORD *)Malloc1((*arg)*
sizeof(WORD),
"ConvertArgument");
3075 i = *arg - ARGHEAD; t = arg + ARGHEAD; r = output;
3080 if ( *arg == -EXPRESSION ) {
3082 return(CreateExpression(BHEAD arg[1]));
3084 if ( *arg == -DOLLAREXPRESSION ) {
3087 d = DolToTerms(BHEAD arg[1]);
3093 output = (WORD *)Malloc1((d->size+1)*
sizeof(WORD),
"Copy of dollar content");
3094 WCOPY(output,d->where,d->size+1);
3095 if ( d->factors ) { M_free(d->factors,
"Dollar factors"); d->factors = 0; }
3096 M_free(d,
"Copy of dollar variable");
3104 output = (WORD *)Malloc1(size*
sizeof(WORD),
"ConvertArgument");
3107 output[0] = 8; output[1] = SYMBOL; output[2] = 4; output[3] = arg[1];
3108 output[4] = 1; output[5] = 1; output[6] = 1; output[7] = 3;
3114 output[0] = 7; output[1] = INDEX; output[2] = 3; output[3] = arg[1];
3115 output[4] = 1; output[5] = 1;
3116 if ( *arg == -MINVECTOR ) output[6] = -3;
3123 output[1] = -arg[1]; output[2] = 1; output[3] = -3;
3126 output[1] = arg[1]; output[2] = 1; output[3] = 3;
3131 output[0] = FUNHEAD+4;
3133 output[2] = FUNHEAD;
3134 for ( i = 3; i <= FUNHEAD; i++ ) output[i] = 0;
3135 output[FUNHEAD+1] = 1;
3136 output[FUNHEAD+2] = 1;
3137 output[FUNHEAD+3] = 3;
3138 output[FUNHEAD+4] = 0;
3156char *TheErrorMessage[] = {
3157 "PolyRatFun not of a type that FORM will expand: incorrect variable inside."
3158 ,
"Division by zero in PolyRatFun encountered in ExpandRat."
3159 ,
"Irregular code in PolyRatFun encountered in ExpandRat."
3160 ,
"Called from ExpandRat."
3161 ,
"WorkSpace overflow. Change parameter WorkSpace in setup file?"
3162 ,
"Illegal term in expanded polyratfun."
3165int ExpandRat(PHEAD WORD *fun)
3167 WORD *r, *rr, *rrr, *tt, *tnext, *arg1, *arg2, *rmin = NULL, *rmininv;
3168 WORD *rcoef, rsize, rcopy, *ow = AT.WorkPointer;
3169 WORD *numerator, *denominator, *rnext;
3170 WORD *thecopy, *rc, ncoef, newcoef, *m, *mm, nco, *outarg = NULL;
3171 UWORD co[2], co1[2], co2[2];
3172 WORD OldPolyFunPow = AR.PolyFunPow;
3173 int i, j, minpow = 0, eppow, first, error = 0, ipoly;
3174 if ( fun[1] == FUNHEAD ) {
return(0); }
3175 tnext = fun + fun[1];
3176 if ( fun[1] == fun[FUNHEAD]+FUNHEAD ) {
3177 if ( fun[2] == 0 ) {
goto done; }
3182 if ( outarg == NULL ) outarg = TermMalloc(
"ExpandRat")+ARGHEAD;
3185 r = fun+FUNHEAD+ARGHEAD;
3186 if ( AR.PolyFunExp == 2 ) {
3187 WORD minpow2 = MAXPOWER, *rrm;
3189 while ( rrm < tnext ) {
3191 if ( minpow2 > 0 ) minpow2 = 0;
3193 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3194 if ( minpow2 > 0 ) minpow2 = 0;
3197 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3198 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3200 else { error = 5;
goto onerror; }
3204 AR.PolyFunPow += minpow2;
3206 while ( r < tnext ) {
3208 i = *r; rrr = outarg; NCOPY(rrr,r,i);
3209 Normalize(BHEAD outarg);
3210 if ( *outarg > 0 )
StoreTerm(BHEAD outarg);
3212 r = fun+FUNHEAD+ARGHEAD;
3216 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = 0;
3221 if ( ToFast(rr,rr) ) {
3222 NEXTARG(rr); fun[1] = rr - fun;
3225 while ( *r ) r += *r;
3226 *rr = r-rr; rr[1] = CLEANFLAG;
3239 arg1 = tt; NEXTARG(tt);
3241 arg2 = tt; NEXTARG(tt);
3242 if ( tt != tnext ) { arg1 = arg2 = NULL; }
3244 }
else { error = 5;
goto onerror; }
3245 if ( arg2 == NULL ) {
3246 if ( *arg1 < 0 ) { fun[2] = CLEANFLAG;
goto done; }
3247 if ( fun[2] == CLEANFLAG )
goto done;
3253 if ( outarg == NULL ) outarg = TermMalloc(
"ExpandRat")+ARGHEAD;
3262 if ( *arg2 == -SYMBOL && arg2[1] == AR.PolyFunVar ) {
3263 rr = r = fun+FUNHEAD+ARGHEAD;
3265 if ( *arg1 == -SYMBOL ) {
3266 if ( arg1[1] == AR.PolyFunVar ) {
3267 *r++ = 4; *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3270 *r++ = 10; *r++ = SYMBOL; *r++ = 6;
3271 *r++ = arg1[1]; *r++ = 1;
3272 *r++ = AR.PolyFunVar; *r++ = -1;
3273 *r++ = 1; *r++ = 1; *r++ = 3; *r = 0;
3274 Normalize(BHEAD rr);
3277 else if ( *arg1 == -SNUMBER ) {
3279 if ( nco == 0 ) { *r++ = 0; }
3281 *r++ = 8; *r++ = SYMBOL; *r++ = 4;
3282 *r++ = AR.PolyFunVar; *r++ = -1;
3283 *r++ = ABS(nco); *r++ = 1;
3284 if ( nco < 0 ) *r++ = -3;
3289 else { error = 2;
goto onerror; }
3294 if ( AR.PolyFunExp == 2 ) {
3295 WORD minpow2 = MAXPOWER, *rrm;
3297 while ( rrm < arg2 ) {
3299 if ( minpow2 > 0 ) minpow2 = 0;
3301 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3302 if ( minpow2 > 0 ) minpow2 = 0;
3305 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3306 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3308 else { error = 5;
goto onerror; }
3312 AR.PolyFunPow += minpow2-1;
3314 while ( m < arg2 ) {
3316 rrr = r++; mm = m + *m;
3317 *r++ = SYMBOL; *r++ = 4; *r++ = AR.PolyFunVar; *r++ = -1;
3318 m++;
while ( m < mm ) *r++ = *m++;
3320 Normalize(BHEAD rrr);
3324 r = rr;
while ( *r ) r += *r;
3327 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = CLEANFLAG;
3334 if ( ToFast(rr,rr) ) {
3338 else { fun[1] = r - fun; }
3343 else if ( *arg2 == -SNUMBER ) {
3345 if ( arg2[1] == 0 ) { error = 1;
goto onerror; }
3346 if ( *arg1 == -SNUMBER ) {
3347 if ( arg1[1] == 0 ) { *r++ = 0; }
3349 co1[0] = ABS(arg1[1]); co1[1] = 1;
3350 co2[0] = 1; co2[1] = ABS(arg2[1]);
3351 MulRat(BHEAD co1,1,co2,1,co,&nco);
3352 *r++ = 4; *r++ = (WORD)(co[0]); *r++ = (WORD)(co[1]);
3353 if ( ( arg1[1] < 0 && arg2[1] > 0 ) ||
3354 ( arg1[1] > 0 && arg2[1] < 0 ) ) *r++ = -3;
3359 else if ( *arg1 == -SYMBOL ) {
3360 *r++ = 8; *r++ = SYMBOL; *r++ = 4;
3361 *r++ = arg1[1]; *r++ = 1;
3362 *r++ = 1; *r++ = ABS(arg2[1]);
3363 if ( arg2[1] < 0 ) *r++ = -3;
3367 else if ( *arg1 < 0 ) { error = 2;
goto onerror; }
3371 if ( AR.PolyFunExp == 2 ) {
3372 WORD minpow2 = MAXPOWER, *rrm;
3374 while ( rrm < arg2 ) {
3376 if ( minpow2 > 0 ) minpow2 = 0;
3378 else if ( ABS(rrm[*rrm-1]) == (*rrm-1) ) {
3379 if ( minpow2 > 0 ) minpow2 = 0;
3382 if ( rrm[1] == SYMBOL && rrm[2] == 4 && rrm[3] == AR.PolyFunVar ) {
3383 if ( rrm[4] < minpow2 ) minpow2 = rrm[4];
3385 else { error = 5;
goto onerror; }
3389 AR.PolyFunPow += minpow2;
3391 while ( m < arg2 ) {
3393 rrr = r++; mm = m + *m;
3394 *r++ = DENOMINATOR; *r++ = FUNHEAD + 2; *r++ = DIRTYFLAG;
3396 *r++ = arg2[0]; *r++ = arg2[1];
3397 m++;
while ( m < mm ) *r++ = *m++;
3399 if ( r < AT.WorkTop && r >= AT.WorkSpace )
3401 Normalize(BHEAD rrr);
3402 if ( ABS(rrr[*rrr-1]) == *rrr-1 ) {
3403 if ( AR.PolyFunPow >= 0 ) {
3407 else if ( rrr[1] == SYMBOL && rrr[2] == 4 &&
3408 rrr[3] == AR.PolyFunVar && rrr[4] <= AR.PolyFunPow ) {
3414 r = rr;
while ( *r ) r += *r;
3416 r = fun + FUNHEAD + ARGHEAD;
3419 *rr = r - rr; rr[1] = CLEANFLAG;
3420 if ( ToFast(rr,rr) ) {
3424 else { fun[1] = r - fun; }
3428 else { error = 0;
goto onerror; }
3433 while ( r < tnext ) {
3434 rr = r + *r; rr -= ABS(rr[-1]);
3436 if ( first ) { minpow = 0; first = 0; rmin = r; }
3437 else if ( minpow > 0 ) { minpow = 0; rmin = r; }
3439 else if ( r[1] != SYMBOL || r[2] != 4 || r[3] != AR.PolyFunVar
3440 || r[4] > MAXPOWER ) { error = 0;
goto onerror; }
3441 else if ( first ) { minpow = r[4]; first = 0; rmin = r; }
3442 else if ( r[4] < minpow ) { minpow = r[4]; rmin = r; }
3460 AT.WorkPointer += AM.MaxTer/
sizeof(WORD);
3461 if ( AT.WorkPointer + (AM.MaxTer/
sizeof(WORD)) >= AT.WorkTop ) {
3462 error = 4;
goto onerror;
3464 rmininv = r = AT.WorkPointer;
3465 rr = rmin; i = *rmin; NCOPY(r,rr,i)
3466 if ( minpow != 0 ) { rmininv[4] = -rmininv[4]; }
3469 rsize = (rsize-1)/2; rr = rcoef + rsize;
3470 for ( i = 0; i < rsize; i++ ) {
3471 rcopy = rcoef[i]; rcoef[i] = rr[i]; rr[i] = rcopy;
3475 ToGeneral(arg1,r,0);
3476 arg1 = r; r += *r; *r++ = 0; rcopy = 0;
3481 rcopy = *r; *r++ = 0;
3486 AT.LeaveNegative = 1;
3487 numerator = MultiplyWithTerm(BHEAD arg1+ARGHEAD,rmininv,0);
3488 AT.LeaveNegative = 0;
3490 r = numerator;
while ( *r ) r += *r;
3491 AT.WorkPointer = r+1;
3492 rcopy = arg2[*arg2]; arg2[*arg2] = 0;
3493 denominator = MultiplyWithTerm(BHEAD arg2+ARGHEAD,rmininv,1);
3494 arg2[*arg2] = rcopy;
3495 r = denominator;
while ( *r ) r += *r;
3496 AT.WorkPointer = r+1;
3503 rr = r + *r; rr -= ABS(rr[-1]);
3505 if ( first ) { minpow = 0; first = 0; }
3506 else if ( minpow > 0 ) { minpow = 0; }
3508 else if ( r[1] != SYMBOL ) { error = 0;
goto onerror; }
3510 for ( i = 3; i < r[2]; i += 2 ) {
3511 if ( r[i] == AR.PolyFunVar ) {
3512 if ( first ) { minpow = r[i+1]; first = 0; }
3513 else if ( r[i+1] < minpow ) minpow = r[i+1];
3518 if ( first ) { minpow = 0; first = 0; }
3519 else if ( minpow > 0 ) minpow = 0;
3529 if ( AR.PolyFunExp == 3 ) {
3530 ipoly = InvPoly(BHEAD denominator,AR.PolyFunPow-minpow,AR.PolyFunVar);
3533 ipoly = InvPoly(BHEAD denominator,AR.PolyFunPow,AR.PolyFunVar);
3545 rrr = rnext - ABS(rnext[-1]);
3549 j = rr[1] - 2; rr += 2;
3551 if ( *rr == AR.PolyFunVar ) { eppow = rr[1];
break; }
3558 for ( i = 0; i <= AR.PolyFunPow-eppow+minpow; i++ ) {
3559 if ( AT.pWorkSpace[ipoly+i] == 0 )
continue;
3564 rr = thecopy = AT.WorkPointer;
3565 while ( rc < rrr ) *rr++ = *rc++;
3567 *rr++ = SYMBOL; *rr++ = 4; *rr++ = AR.PolyFunVar; *rr++ = i;
3569 ncoef = REDLENG(rnext[-1]);
3570 MulRat(BHEAD (UWORD *)rrr,ncoef,
3571 (UWORD *)(AT.pWorkSpace[ipoly+i])+1,AT.pWorkSpace[ipoly+i][0]
3572 ,(UWORD *)rr,&newcoef);
3573 ncoef = ABS(newcoef); rr += 2*ncoef;
3574 newcoef = INCLENG(newcoef);
3576 *thecopy = rr - thecopy;
3577 AT.WorkPointer = rr;
3578 Normalize(BHEAD thecopy);
3579 if ( *thecopy > 0 )
StoreTerm(BHEAD thecopy);
3580 AT.WorkPointer = thecopy;
3587 rr = fun + FUNHEAD; r = rr + ARGHEAD;
3590 fun[1] = FUNHEAD+2; fun[2] = CLEANFLAG;
3591 fun[FUNHEAD] = -SNUMBER; fun[FUNHEAD+1] = 0;
3594 while ( *r ) r += *r;
3595 rr[0] = r-rr; rr[1] = CLEANFLAG;
3596 if ( ToFast(rr,rr) ) { NEXTARG(rr); fun[1] = rr-fun; }
3597 else { fun[1] = r-fun; }
3602 if ( outarg ) TermFree(outarg-ARGHEAD,
"ExpandRat");
3603 AR.PolyFunPow = OldPolyFunPow;
3604 AT.WorkPointer = ow;
3605 AN.PolyNormFlag = 1;
3608 if ( outarg ) TermFree(outarg-ARGHEAD,
"ExpandRat");
3609 AR.PolyFunPow = OldPolyFunPow;
3610 AT.WorkPointer = ow;
3611 MLOCK(ErrorMessageLock);
3612 MesPrint(TheErrorMessage[error]);
3613 MUNLOCK(ErrorMessageLock);
3635int InvPoly(PHEAD WORD *inpoly, WORD maxpow, WORD sym)
3637 int needed, inpointers, outpointers, maxinput = 0, i, j;
3638 WORD *t, *tt, *ttt, *w, *c, *cc, *ccc, lenc, lenc1, lenc2, rc, *c1, *c2;
3642 needed = (maxpow+1)*2;
3643 WantAddPointers(needed);
3644 inpointers = AT.pWorkPointer;
3645 outpointers = AT.pWorkPointer+maxpow+1;
3646 for ( i = 0; i < needed; i++ ) AT.pWorkSpace[inpointers+i] = 0;
3656 if ( t[1] != 1 || t[2] != 1 || t[3] != 3 )
goto onerror;
3657 AT.pWorkSpace[inpointers] = 0;
3659 else if ( t[1] != SYMBOL || t[2] != 4 || t[3] != sym || t[4] < 0 )
goto onerror;
3660 else if ( t[4] > maxpow ) {}
3662 if ( t[4] > maxinput ) maxinput = t[4];
3663 AT.pWorkSpace[inpointers+t[4]] = w;
3664 tt = t + *t; rc = -*--tt;
3665 rc = REDLENG(rc); *w++ = rc;
3667 while ( ttt < tt ) *w++ = *ttt++;
3675 AT.pWorkSpace[outpointers] = w;
3676 *w++ = 1; *w++ = 1; *w++ = 1;
3677 c = TermMalloc(
"InvPoly");
3678 c1 = TermMalloc(
"InvPoly");
3679 c2 = TermMalloc(
"InvPoly");
3680 for ( j = 1; j <= maxpow; j++ ) {
3684 if ( ( cc = AT.pWorkSpace[inpointers+j] ) != 0 ) {
3686 i = 2*ABS(lenc); ccc = c;
3690 for ( i = MiN(j-1,maxinput); i > 0; i-- ) {
3694 if ( AT.pWorkSpace[inpointers+i] == 0
3695 || AT.pWorkSpace[outpointers+j-i] == 0 ) {
3698 if ( MulRat(BHEAD (UWORD *)(AT.pWorkSpace[inpointers+i]+1),AT.pWorkSpace[inpointers+i][0],
3699 (UWORD *)(AT.pWorkSpace[outpointers+j-i]+1),AT.pWorkSpace[outpointers+j-i][0],
3700 (UWORD *)c1,&lenc1) )
goto calcerror;
3702 cc = c; c = c1; c1 = cc;
3706 if ( AddRat(BHEAD (UWORD *)c,lenc,(UWORD *)c1,lenc1,(UWORD *)c2,&lenc2) )
3708 cc = c; c = c2; c2 = cc;
3716 if ( lenc == 0 ) AT.pWorkSpace[outpointers+j] = 0;
3718 AT.pWorkSpace[outpointers+j] = w;
3720 i = 2*ABS(lenc); ccc = c;
3725 TermFree(c2,
"InvPoly");
3726 TermFree(c1,
"InvPoly");
3727 TermFree(c ,
"InvPoly");
3729 return(outpointers);
3731 MLOCK(ErrorMessageLock);
3732 MesPrint(
"Incorrect symbol field in InvPoly.");
3733 MUNLOCK(ErrorMessageLock);
3737 MLOCK(ErrorMessageLock);
3738 MesPrint(
"Called from InvPoly.");
3739 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)