Skip to content

Commit 76a32ab

Browse files
author
jkuipers
committed
fixed more collateral damage in polynomial divison
1 parent 47502eb commit 76a32ab

1 file changed

Lines changed: 50 additions & 48 deletions

File tree

sources/poly.cc

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)