A monomial represented by a coefficient and variable-to-power mapping.
| 21 | |
| 22 | |
| 23 | class Monomial: |
| 24 | """A monomial represented by a coefficient and variable-to-power mapping.""" |
| 25 | |
| 26 | def __init__( |
| 27 | self, variables: dict[int, int], coeff: int | float | Fraction | None = None |
| 28 | ) -> None: |
| 29 | """Create a monomial with the given variables and coefficient. |
| 30 | |
| 31 | Args: |
| 32 | variables: Dictionary mapping variable indices to their powers. |
| 33 | coeff: The coefficient (defaults to 0 if empty, 1 otherwise). |
| 34 | |
| 35 | Examples: |
| 36 | >>> Monomial({1: 1}) # (a_1)^1 |
| 37 | >>> Monomial({1: 3, 2: 2}, 12) # 12(a_1)^3(a_2)^2 |
| 38 | """ |
| 39 | self.variables = dict() |
| 40 | |
| 41 | if coeff is None: |
| 42 | coeff = Fraction(0, 1) if len(variables) == 0 else Fraction(1, 1) |
| 43 | elif coeff == 0: |
| 44 | self.coeff = Fraction(0, 1) |
| 45 | return |
| 46 | |
| 47 | if len(variables) == 0: |
| 48 | self.coeff = Monomial._rationalize_if_possible(coeff) |
| 49 | return |
| 50 | |
| 51 | for i in variables: |
| 52 | if variables[i] != 0: |
| 53 | self.variables[i] = variables[i] |
| 54 | self.coeff = Monomial._rationalize_if_possible(coeff) |
| 55 | |
| 56 | @staticmethod |
| 57 | def _rationalize_if_possible( |
| 58 | num: int | float | Fraction, |
| 59 | ) -> Fraction | float: |
| 60 | """Convert numbers to Fraction when possible. |
| 61 | |
| 62 | Args: |
| 63 | num: A numeric value. |
| 64 | |
| 65 | Returns: |
| 66 | A Fraction if the input is Rational, otherwise the original value. |
| 67 | """ |
| 68 | if isinstance(num, Rational): |
| 69 | res = Fraction(num, 1) |
| 70 | return Fraction(res.numerator, res.denominator) |
| 71 | else: |
| 72 | return num |
| 73 | |
| 74 | def equal_upto_scalar(self, other: object) -> bool: |
| 75 | """Check if other is a monomial equivalent to self up to scalar multiple. |
| 76 | |
| 77 | Args: |
| 78 | other: Another Monomial to compare. |
| 79 | |
| 80 | Returns: |
no outgoing calls