PageRenderTime 60ms CodeModel.GetById 1ms RepoModel.GetById 0ms app.codeStats 1ms

/sympycore/heads/neg.py

https://github.com/escheffel/pymaclab
Python | 127 lines | 99 code | 24 blank | 4 comment | 24 complexity | 167b22cdda09017c234a91c9973774f4 MD5 | raw file
  1. __all__ = ['NEG']
  2. from .base import heads_precedence, ArithmeticHead
  3. from ..core import init_module
  4. init_module.import_heads()
  5. init_module.import_lowlevel_operations()
  6. init_module.import_numbers()
  7. class NegHead(ArithmeticHead):
  8. """
  9. NegHead represents negative unary operation where operand (data)
  10. is an expression.
  11. """
  12. op_mth = '__neg__'
  13. def is_data_ok(self, cls, data):
  14. if not isinstance(data, cls):
  15. return '%s data part must be %s instance but got %s' % (self, cls, type(data))
  16. def __repr__(self): return 'NEG'
  17. def new(self, cls, expr, evaluate=True):
  18. if not evaluate:
  19. return cls(self, expr)
  20. h, d = expr.pair
  21. if h is NUMBER:
  22. return cls(NUMBER, -d)
  23. if h is TERM_COEFF:
  24. t, c = d
  25. return TERM_COEFF.new(cls, (t, -c))
  26. return cls(NEG, expr)
  27. def reevaluate(self, cls, expr):
  28. return -expr
  29. def data_to_str_and_precedence(self, cls, expr):
  30. if cls.algebra_options.get('evaluate_addition'):
  31. if expr.head is NEG:
  32. expr = expr.data
  33. return expr.head.data_to_str_and_precedence(cls, expr.data)
  34. s, s_p = expr.head.data_to_str_and_precedence(cls, expr.data)
  35. neg_p = heads_precedence.NEG
  36. if s_p < neg_p:
  37. return '-(' + s + ')', neg_p
  38. return '-' + s, neg_p
  39. def to_lowlevel(self, cls, data, pair):
  40. if isinstance(data, numbertypes):
  41. return -data
  42. if data.head is NUMBER:
  43. return -data.data
  44. return cls(TERM_COEFF, (data, -1))
  45. def term_coeff(self, cls, expr):
  46. e = expr.data
  47. t, c = e.head.term_coeff(cls, e)
  48. return t, -c
  49. def scan(self, proc, cls, expr, target):
  50. expr.head.scan(proc, cls, expr.data, target)
  51. proc(cls, self, expr, target)
  52. def walk(self, func, cls, operand, target):
  53. operand1 = operand.head.walk(func, cls, operand.data, operand)
  54. if operand1 is operand:
  55. return func(cls, self, operand, target)
  56. r = self.new(cls, operand1)
  57. return func(cls, r.head, r.data, r)
  58. def to_TERM_COEFF_DICT(self, Algebra, data, expr):
  59. return -data.head.to_TERM_COEFF_DICT(Algebra, data.data, data)
  60. def to_ADD(self, Algebra, data, expr):
  61. return -data.head.to_ADD(Algebra, data.data, data)
  62. def algebra_pos(self, Algebra, expr):
  63. return expr
  64. def algebra_neg(self, Algebra, expr):
  65. if Algebra.algebra_options.get('evaluate_addition'):
  66. return expr.data
  67. return Algebra(NEG, expr)
  68. def algebra_add_number(self, Algebra, lhs, rhs, inplace):
  69. return self.algebra_add(Algebra, lhs, Algebra(NUMBER, rhs), inplace)
  70. def algebra_add(self, Algebra, lhs, rhs, inplace):
  71. rhead, rdata = rhs.pair
  72. if rhead is ADD:
  73. data = [lhs] + rdata
  74. elif rhead is TERM_COEFF_DICT or rhead is EXP_COEFF_DICT:
  75. data = [lhs] + rhs.to(ADD).data
  76. else:
  77. data = [lhs, rhs]
  78. if Algebra.algebra_options.get('evaluate_addition'):
  79. ADD.combine_add_list(Algebra, data)
  80. return add_new(Algebra, data)
  81. def algebra_mul_number(self, Algebra, lhs, rhs, inplace):
  82. if Algebra.algebra_options.get('is_additive_group_commutative'):
  83. term, coeff = lhs.head.term_coeff(Algebra, lhs)
  84. return term_coeff_new(Algebra, (term, coeff * rhs))
  85. else:
  86. if Algebra.algebra_options.get('evaluate_addition'):
  87. if rhs == 0:
  88. return Algebra(NUMBER, 0)
  89. term, coeff = lhs.head.term_coeff(Algebra, lhs)
  90. return term_coeff_new(Algebra, (term, coeff * rhs))
  91. return mul_new(Algebra, [lhs, Algebra(NUMBER, rhs)])
  92. def algebra_mul(self, Algebra, lhs, rhs, inplace):
  93. ldata = lhs.data
  94. if Algebra.algebra_options.get('is_additive_group_commutative'):
  95. return super(type(self), self).algebra_mul(Algebra, lhs, rhs, inplace)
  96. else:
  97. if Algebra.algebra_options.get('evaluate_addition'):
  98. rhead, rdata = rhs.pair
  99. if rhead is NUMBER:
  100. return ldata.head.algebra_mul_number(Algebra, ldata, -rdata, inplace)
  101. return super(type(self), self).algebra_mul(Algebra, lhs, rhs, inplace)
  102. return mul_new(Algebra, [lhs, rhs])
  103. NEG = NegHead()