multipoly.py 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. class Variable:
  2. def __init__(self, name):
  3. self.name = name
  4. def __pow__(self, n):
  5. expr = MultiplyExpression()
  6. expr.set_symbol(self.name, n)
  7. return expr
  8. def termify(self):
  9. expr = MultiplyExpression()
  10. expr.set_symbol(self.name, 1)
  11. return expr
  12. class MultiplyExpression:
  13. def __init__(self):
  14. self.coeff = None
  15. self.symbols = {}
  16. def clean(self):
  17. for symbol in list(self.symbols.keys()):
  18. if self.symbols[symbol] == 0:
  19. del self.symbols[symbol]
  20. def set_symbol(self, var_name, power):
  21. self.symbols[var_name] = power
  22. def __mul__(self, expr):
  23. result = MultiplyExpression()
  24. result.coeff = self.coeff
  25. result.symbols = self.symbols.copy()
  26. if hasattr(expr, "field"):
  27. if result.coeff is None:
  28. result.coeff = expr
  29. else:
  30. result.coeff *= expr
  31. return result
  32. if isinstance(expr, Variable):
  33. expr = expr.termify()
  34. for var_name, power in expr.symbols.items():
  35. if var_name in result.symbols:
  36. result.symbols[var_name] += power
  37. else:
  38. result.symbols[var_name] = power
  39. return result
  40. def __add__(self, expr):
  41. return MultivariatePolynomial([self, expr])
  42. def __str__(self):
  43. repr = ""
  44. first = True
  45. if self.coeff is not None:
  46. repr += str(self.coeff)
  47. first = False
  48. for var_name, power in self.symbols.items():
  49. if first:
  50. first = False
  51. else:
  52. repr += " "
  53. if power == 1:
  54. repr += var_name
  55. else:
  56. repr += var_name + "^" + str(power)
  57. return repr
  58. class MultivariatePolynomial:
  59. def __init__(self, terms=[]):
  60. self.terms = terms
  61. def __add__(self, term):
  62. if isinstance(term, Variable):
  63. term = term.termify()
  64. # Delete ^0 variables
  65. term.clean()
  66. # Skip zero terms
  67. if term.coeff is None or term.coeff == 0:
  68. return self
  69. result = MultivariatePolynomial(self.terms[:])
  70. result.terms.append(term)
  71. return result
  72. def __str__(self):
  73. repr = ""
  74. first = True
  75. for term in self.terms:
  76. if first:
  77. first = False
  78. else:
  79. repr += " + "
  80. repr += str(term)
  81. return repr
  82. if __name__ == "__main__":
  83. from finite_fields import finitefield
  84. p = 0x40000000000000000000000000000000224698fc094cf91b992d30ed00000001
  85. fp = finitefield.IntegersModP(p)
  86. x = Variable("X")
  87. y = Variable("Y")
  88. z = Variable("Z")
  89. p = x**3 * y**2 * x**2 * fp(5) * fp(2) + x**3 * y + z + fp(6)
  90. print(p)