Perform polynomial long division. Args: other: The divisor Polynomial. Returns: A tuple (quotient, remainder). Raises: ValueError: If other is not a Polynomial or is zero.
(self, other: Polynomial)
| 656 | return " + ".join(str(m) for m in sorted_monos if m.coeff != Fraction(0, 1)) |
| 657 | |
| 658 | def poly_long_division(self, other: Polynomial) -> tuple[Polynomial, Polynomial]: |
| 659 | """Perform polynomial long division. |
| 660 | |
| 661 | Args: |
| 662 | other: The divisor Polynomial. |
| 663 | |
| 664 | Returns: |
| 665 | A tuple (quotient, remainder). |
| 666 | |
| 667 | Raises: |
| 668 | ValueError: If other is not a Polynomial or is zero. |
| 669 | """ |
| 670 | if not isinstance(other, Polynomial): |
| 671 | raise ValueError("Can only divide by another Polynomial.") |
| 672 | |
| 673 | if len(other.all_monomials()) == 0: |
| 674 | raise ValueError("Cannot divide by zero polynomial.") |
| 675 | |
| 676 | quotient = Polynomial([]) |
| 677 | remainder = self.clone() |
| 678 | |
| 679 | divisor_monos = sorted( |
| 680 | other.all_monomials(), |
| 681 | key=lambda m: sorted(m.variables.items(), reverse=True), |
| 682 | reverse=True, |
| 683 | ) |
| 684 | divisor_lead = divisor_monos[0] |
| 685 | |
| 686 | while remainder.all_monomials() and max( |
| 687 | remainder.variables(), default=-1 |
| 688 | ) >= max(other.variables(), default=-1): |
| 689 | remainder_monos = sorted( |
| 690 | remainder.all_monomials(), |
| 691 | key=lambda m: sorted(m.variables.items(), reverse=True), |
| 692 | reverse=True, |
| 693 | ) |
| 694 | remainder_lead = remainder_monos[0] |
| 695 | |
| 696 | if not all( |
| 697 | remainder_lead.variables.get(var, 0) |
| 698 | >= divisor_lead.variables.get(var, 0) |
| 699 | for var in divisor_lead.variables |
| 700 | ): |
| 701 | break |
| 702 | |
| 703 | lead_quotient = remainder_lead / divisor_lead |
| 704 | quotient = quotient + Polynomial([lead_quotient]) |
| 705 | |
| 706 | remainder = remainder - (Polynomial([lead_quotient]) * other) |
| 707 | |
| 708 | return quotient, remainder |