@@ -1495,7 +1495,7 @@ void poly::divmod_univar (const poly &a, const poly &b, poly &q, poly &r, int va
14951495 * Note: the hashing trick as in multiplication cannot be used
14961496 * easily, since there is no tight upperbound on the exponents in
14971497 * the answer.
1498- *
1498+
14991499 * For details, see M. Monagan, "Polynomial Division using Dynamic
15001500 * Array, Heaps, and Packed Exponent Vectors"
15011501 */
@@ -1536,7 +1536,6 @@ void poly::divmod_heap (const poly &a, const poly &b, poly &q, poly &r, bool onl
15361536
15371537 // allocate heap
15381538 int nb=b.number_of_terms ();
1539-
15401539 WantAddPointers (nb);
15411540 WORD **heap = AT.pWorkSpace + AT.pWorkPointer ;
15421541
@@ -1548,7 +1547,7 @@ void poly::divmod_heap (const poly &a, const poly &b, poly &q, poly &r, bool onl
15481547 heap[0 ][2 ] = -1 ;
15491548 WCOPY (&heap[0 ][3 ], &a[1 ], a[1 ]);
15501549 heap[0 ][3 ] = a[a[1 ]];
1551-
1550+
15521551 int qi=1 , ri=1 ;
15531552
15541553 int s = nb;
@@ -1613,55 +1612,58 @@ void poly::divmod_heap (const poly &a, const poly &b, poly &q, poly &r, bool onl
16131612 insert.pop_back ();
16141613 }
16151614
1616- // prepare the element to add to the heap
1617- if (p[1 ]==0 ) {
1618- p[0 ] += a[p[0 ]];
1619- if (p[0 ]==a[0 ]) break ;
1620- WCOPY (&p[3 ], &a[p[0 ]], a[p[0 ]]);
1621- p[3 ] = p[2 +p[3 ]];
1622- }
1623- else {
1624- if (!this_insert)
1625- p[1 ] += q[p[1 ]];
1626- this_insert = false ;
1627-
1628- if (p[1 ]==qi) { s++; break ; }
1629-
1630- for (int i=0 ; i<AN.poly_num_vars ; i++)
1631- p[4 +i] = b[p[0 ]+1 +i] + q[p[1 ]+1 +i];
1632-
1633- // if both polynomials are modulo p^1, use integer calculus
1634- if (both_mod_small) {
1635- p[4 +AN.poly_num_vars ] = ((LONG)b[p[0 ]+1 +AN.poly_num_vars ]*b[p[0 ]+b[p[0 ]]-1 ]*
1636- q[p[1 ]+1 +AN.poly_num_vars ]*q[p[1 ]+q[p[1 ]]-1 ]) % q.modp ;
1637- if (p[4 +AN.poly_num_vars ]==0 )
1638- p[3 ]=0 ;
1615+ // add elements to the heap
1616+ while (true ) {
1617+ // prepare the element
1618+ if (p[1 ]==0 ) {
1619+ p[0 ] += a[p[0 ]];
1620+ if (p[0 ]==a[0 ]) break ;
1621+ WCOPY (&p[3 ], &a[p[0 ]], a[p[0 ]]);
1622+ p[3 ] = p[2 +p[3 ]];
1623+ }
1624+ else {
1625+ if (!this_insert)
1626+ p[1 ] += q[p[1 ]];
1627+ this_insert = false ;
1628+
1629+ if (p[1 ]==qi) { s++; break ; }
1630+
1631+ for (int i=0 ; i<AN.poly_num_vars ; i++)
1632+ p[4 +i] = b[p[0 ]+1 +i] + q[p[1 ]+1 +i];
1633+
1634+ // if both polynomials are modulo p^1, use integer calculus
1635+ if (both_mod_small) {
1636+ p[4 +AN.poly_num_vars ] = ((LONG)b[p[0 ]+1 +AN.poly_num_vars ]*b[p[0 ]+b[p[0 ]]-1 ]*
1637+ q[p[1 ]+1 +AN.poly_num_vars ]*q[p[1 ]+q[p[1 ]]-1 ]) % q.modp ;
1638+ if (p[4 +AN.poly_num_vars ]==0 )
1639+ p[3 ]=0 ;
1640+ else {
1641+ if (p[4 +AN.poly_num_vars ] > +q.modp /2 ) p[4 +AN.poly_num_vars ] -= q.modp ;
1642+ if (p[4 +AN.poly_num_vars ] < -q.modp /2 ) p[4 +AN.poly_num_vars ] += q.modp ;
1643+ p[3 ] = SGN (p[4 +AN.poly_num_vars ]);
1644+ p[4 +AN.poly_num_vars ] = ABS (p[4 +AN.poly_num_vars ]);
1645+ }
1646+ }
16391647 else {
1640- if (p[4 +AN.poly_num_vars ] > +q.modp /2 ) p[4 +AN.poly_num_vars ] -= q.modp ;
1641- if (p[4 +AN.poly_num_vars ] < -q.modp /2 ) p[4 +AN.poly_num_vars ] += q.modp ;
1642- p[3 ] = SGN (p[4 +AN.poly_num_vars ]);
1643- p[4 +AN.poly_num_vars ] = ABS (p[4 +AN.poly_num_vars ]);
1648+ // otherwise, use form long calculus
1649+ MulLong ((UWORD *)&b[p[0 ]+1 +AN.poly_num_vars ], b[p[0 ]+b[p[0 ]]-1 ],
1650+ (UWORD *)&q[p[1 ]+1 +AN.poly_num_vars ], q[p[1 ]+q[p[1 ]]-1 ],
1651+ (UWORD *)&p[4 +AN.poly_num_vars ], &p[3 ]);
1652+ if (q.modp !=0 ) TakeNormalModulus ((UWORD *)&p[4 +AN.poly_num_vars ], &p[3 ],
1653+ modq, nmodq, NOUNPACK);
16441654 }
1655+
1656+ p[3 ] *= -1 ;
16451657 }
1646- else {
1647- // otherwise, use form long calculus
1648- MulLong ((UWORD *)&b[p[0 ]+1 +AN.poly_num_vars ], b[p[0 ]+b[p[0 ]]-1 ],
1649- (UWORD *)&q[p[1 ]+1 +AN.poly_num_vars ], q[p[1 ]+q[p[1 ]]-1 ],
1650- (UWORD *)&p[4 +AN.poly_num_vars ], &p[3 ]);
1651- if (q.modp !=0 ) TakeNormalModulus ((UWORD *)&p[4 +AN.poly_num_vars ], &p[3 ],
1652- modq, nmodq, NOUNPACK);
1653- }
1654-
1655- p[3 ] *= -1 ;
1658+
1659+ // no hashing
1660+ p[2 ] = -1 ;
1661+
1662+ // add it to a heap element
1663+ swap (heap[nheap],p);
1664+ push_heap (BHEAD heap, ++nheap);
1665+ break ;
16561666 }
1657-
1658- // no hashing
1659- p[2 ] = -1 ;
1660-
1661- // add it to a heap element if possible, otherwise push it
1662-
1663- swap (heap[nheap],p);
1664- push_heap (BHEAD heap, ++nheap);
16651667 }
16661668 while (t[0 ]==-1 || (nheap>0 && monomial_compare (BHEAD heap[0 ]+3 , t+3 )==0 ));
16671669
0 commit comments