Macaulay2 Engine
Loading...
Searching...
No Matches

◆ powerseries_division_algorithm()

Nterm * PolyRing::powerseries_division_algorithm ( Nterm * f,
Nterm * g,
Nterm *& quot ) const
protected

Definition at line 1553 of file poly.cpp.

1556{
1557 // This is intended for use when there is one variable, inverses are present,
1558 // and the coefficient ring is a field, or is ZZ.
1559 // The algorithm used is as follows.
1560 // Given a non-zero polynomial f = f(t,t^-1), let v(f) = top - bottom
1561 // where top is the largest exponent in f, and bottom is the smallest.
1562 // So if f is a monomial, v(f) = 0. Also, v(fg) = v(f)+v(g) (at least if
1563 // the
1564 // coefficient ring is a domain), and v(f) >= 0 always.
1565 // The algorithm is as follows:
1566 // Reduce f = f0 by lt(g) to obtain f1, then again to obtain f2, etc.
1567 // So v(f1) >= v(f2) >= ... >= v(fi),
1568 // and either fi = 0, v(fi) < v(g), or v(f(i+1)) > v(fi).
1569 // In this case, the remainder returned is fi.
1570 // (Note: the last case won't happen if the coefficients are a field, or the
1571 // lead coefficient of g is a unit).
1572
1573 // This is intended for use when the monomial order has an initial weight
1574 // vector and the first
1575 // term of the divisor's weight value is strictly greater than the other
1576 // terms.
1577 // AND where (all) inverses are present,
1578 // and the coefficient ring is a field, or is ZZ.
1579 // The algorithm used is as follows.
1580 // Given a non-zero polynomial f = f(t,t^-1), let v(f) = top - bottom
1581 // where top is the weight vec value of the first monomial of f, and bottom
1582 // is the weight vec value
1583 // for the last term of f.
1584 // So if f is a monomial, v(f) = 0. Also, v(fg) = v(f)+v(g) (at least if
1585 // the
1586 // coefficient ring is a domain), and v(f) >= 0 always.
1587 // The algorithm is as follows:
1588 // Reduce f = f0 by lt(g) to obtain f1, then again to obtain f2, etc.
1589 // So v(f1) >= v(f2) >= ... >= v(fi),
1590 // and either fi = 0, v(fi) < v(g), or v(f(i+1)) > v(fi).
1591 // In this case, the remainder returned is fi.
1592 // (Note: the last case won't happen if the coefficients are a field, or the
1593 // lead coefficient of g is a unit).
1594
1595 // This returns the remainder, and sets quot to be the quotient.
1596
1597 ring_elem a = copy(f);
1598 Nterm *t = a;
1599 Nterm *b = g;
1600
1601 if (!M_->weight_value_exists())
1602 {
1603 throw exc::engine_error("no method for division in this ring");
1604 }
1605
1606 Nterm divhead;
1607 Nterm remhead;
1608 Nterm *divt = &divhead;
1609 Nterm *remt = &remhead;
1610 Nterm *nextterm = new_term();
1611 long gval = 0, flast = 0;
1612
1613 if (t != nullptr)
1614 {
1615 Nterm *z = t;
1616 for (; z->next != nullptr; z = z->next)
1617 ;
1618
1619 flast = M_->first_weight_value(z->monom);
1620 }
1621
1622 if (b != nullptr)
1623 {
1624 long gfirst, glast;
1625 Nterm *z = b;
1626
1627 if (z->next == nullptr)
1628 gval = 0;
1629 else
1630 {
1631 gfirst = M_->first_weight_value(z->monom);
1632 long gsecond = M_->first_weight_value(z->next->monom);
1633 if (gfirst == gsecond)
1634 {
1635 // In this case, we return silently
1636 throw exc::internal_error("division algorithm for this element is not implemented");
1637 }
1638 for (; z->next != nullptr; z = z->next)
1639 ;
1640 glast = M_->first_weight_value(z->monom);
1641 gval = gfirst - glast;
1642 }
1643 }
1644
1645 // buffer o;
1646 while (t != nullptr)
1647 {
1648 long ffirst;
1649
1650 ffirst = M_->first_weight_value(t->monom);
1651 long fval = ffirst - flast;
1652
1653 // std::cout << "f: "; dNterm(this, t); std::cout << std::endl;
1654 // std::cout << "g: "; dNterm(this, g); std::cout << std::endl;
1655 if (fval >= gval and M_->divides(g->monom, t->monom))
1656 //if (fval >= gval)
1657 {
1658 // o << "t = "; elem_text_out(o,t); o << newline;
1659 a = t;
1660 bool cancelled = imp_attempt_to_cancel_lead_term(
1661 a, g, nextterm->coeff, nextterm->monom);
1662 t = a;
1663 // o << " new t = "; elem_text_out(o,t); o << newline;
1664 // o << " cancelled = " << (cancelled ? "true" : "false") <<
1665 // newline;
1666 // o << " coeff = "; K_->elem_text_out(o,nextterm->coeff); o <<
1667 // newline;
1668 // emit(o.str());
1669 if (!K_->is_zero(nextterm->coeff))
1670 {
1671 divt->next = nextterm;
1672 divt = divt->next;
1673 nextterm = new_term();
1674 }
1675 if (!cancelled)
1676 {
1677 remt->next = t;
1678 remt = remt->next;
1679 t = t->next;
1680 }
1681 }
1682 else
1683 {
1684 remt->next = t;
1685 remt = remt->next;
1686 t = t->next;
1687 }
1688 }
1689
1690 nextterm = nullptr;
1691 remt->next = nullptr;
1692 divt->next = nullptr;
1693 quot = divhead.next;
1694 return remhead.next;
1695}
virtual ring_elem copy(const ring_elem f) const
Definition poly.cpp:653
bool imp_attempt_to_cancel_lead_term(ring_elem &f, ring_elem g, ring_elem &coeff, monomial monom) const
Definition poly.cpp:1010
Nterm * new_term() const
Definition poly.cpp:146
const Ring * K_
Definition polyring.hpp:123
const Monoid * M_
Definition polyring.hpp:124
Nterm * next
Definition ringelem.hpp:157
ring_elem coeff
Definition ringelem.hpp:158
int monom[1]
Definition ringelem.hpp:160

References Nterm::coeff, copy(), imp_attempt_to_cancel_lead_term(), PolynomialRing::K_, PolynomialRing::M_, Nterm::monom, new_term(), and Nterm::next.

Referenced by remainderAndQuotient().