PageRenderTime 54ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/sympycore/heads/symbol.py

https://github.com/escheffel/pymaclab
Python | 222 lines | 185 code | 34 blank | 3 comment | 64 complexity | 2bf8878efdd65cb47a0236d86ebf03dd MD5 | raw file
  1. __all__ = ['SYMBOL']
  2. import re
  3. from ..core import init_module
  4. init_module.import_heads()
  5. init_module.import_numbers()
  6. init_module.import_lowlevel_operations()
  7. from .base import AtomicHead, heads_precedence, Expr, Pair, ArithmeticHead, NotImplementedHeadMethod
  8. _is_atomic = re.compile(r'\A\w+\Z').match
  9. class SymbolHead(AtomicHead):
  10. """
  11. SymbolHead is a head for symbols, data can be any Python object.
  12. """
  13. def new(self, cls, data, evaluate=True):
  14. return cls(self, data)
  15. def reevaluate(self, cls, data):
  16. return cls(self, data)
  17. def is_data_ok(self, cls, data):
  18. return
  19. def __repr__(self): return 'SYMBOL'
  20. def data_to_str_and_precedence(self, cls, data):
  21. if isinstance(data, Expr):
  22. h, d = data.pair
  23. return h.data_to_str_and_precedence(cls, d)
  24. s = str(data)
  25. if _is_atomic(s):
  26. return s, heads_precedence.SYMBOL
  27. return s, 0.0 # force parenthesis
  28. def to_EXP_COEFF_DICT(self, cls, data, expr, variables = None):
  29. variables = EXP_COEFF_DICT.combine_variables(data, variables)
  30. exp = EXP_COEFF_DICT.make_exponent(data, variables)
  31. assert len(exp)==len(variables), `exp, variables, i, data`
  32. return cls(EXP_COEFF_DICT, Pair(variables, {exp:1}))
  33. def commutative_mul_number(self, cls, lhs, rhs):
  34. return term_coeff_new(cls, (lhs, rhs))
  35. non_commutative_mul_number = commutative_mul_number
  36. def pow(self, cls, base, exp):
  37. if type(exp) is cls and exp.head is NUMBER:
  38. exp = exp.data
  39. return pow_new(cls, (base, exp))
  40. def pow_number(self, cls, base, exp):
  41. if exp==1: return base
  42. if exp==0: return cls(NUMBER, 1)
  43. return cls(POW, (base, exp))
  44. def expand(self, cls, expr):
  45. return expr
  46. def expand_intpow(self, cls, expr, intexp):
  47. if intexp==0:
  48. return cls(NUMBER, 1)
  49. return cls(POW, (expr, intexp))
  50. def diff(self, cls, data, expr, symbol, order, cache={}):
  51. if order==0:
  52. return expr
  53. if data == symbol:
  54. assert order>0,`order`
  55. return cls(NUMBER, int(order==1))
  56. return cls(NUMBER, 0)
  57. def fdiff(self, cls, data, expr, argument_index, order):
  58. vcls = cls.get_value_algebra()
  59. dcls = cls.get_differential_algebra()
  60. d = dcls(FDIFF, vcls(NUMBER, argument_index))**order
  61. return cls(APPLY, (d, (expr,)))
  62. def apply(self, cls, data, func, args):
  63. return cls(APPLY, (func, args))
  64. def integrate_indefinite(self, cls, data, expr, x):
  65. if data==x:
  66. return cls(TERM_COEFF, (cls(POW, (expr, 2)), mpq((1,2))))
  67. return cls(BASE_EXP_DICT, {expr:1, cls(SYMBOL, x):1})
  68. def integrate_definite(self, cls, data, expr, x, a, b):
  69. if data==x:
  70. return (b**2-a**2)/2
  71. return expr*(b-a)
  72. def to_TERM_COEFF_DICT(self, Algebra, data, expr):
  73. return expr
  74. def to_MUL(self, Algebra, data, expr):
  75. return expr
  76. def to_ADD(self, cls, data, expr):
  77. return expr
  78. def algebra_pos(self, Algebra, expr):
  79. return expr
  80. def algebra_neg(self, Algebra, expr):
  81. if Algebra.algebra_options.get('is_additive_group_commutative'):
  82. if Algebra.algebra_options.get('evaluate_addition'):
  83. return Algebra(TERM_COEFF, (expr, -1))
  84. return Algebra(NEG, expr)
  85. def algebra_add_number(self, Algebra, lhs, rhs, inplace):
  86. if Algebra.algebra_options.get('evaluate_addition'):
  87. if not rhs:
  88. return lhs
  89. if Algebra.algebra_options.get('is_additive_group_commutative'):
  90. return Algebra(TERM_COEFF_DICT, {Algebra(NUMBER, 1): rhs, lhs:1})
  91. return Algebra(ADD, [lhs, Algebra(NUMBER, rhs)])
  92. def algebra_add(self, Algebra, lhs, rhs, inplace):
  93. rhead, rdata = rhs.pair
  94. if Algebra.algebra_options.get('is_additive_group_commutative'):
  95. ldata = lhs.data
  96. if Algebra.algebra_options.get('evaluate_addition'):
  97. if rhead is ADD or rhead is EXP_COEFF_DICT or rhead is MUL or rhead is NEG:
  98. rhead, rdata = rhs.to(TERM_COEFF_DICT).pair
  99. if rhead is SYMBOL:
  100. if ldata == rdata:
  101. return Algebra(TERM_COEFF, (lhs, 2))
  102. return Algebra(TERM_COEFF_DICT, {lhs: 1, rhs: 1})
  103. if rhead is NUMBER:
  104. if rdata:
  105. return Algebra(TERM_COEFF_DICT, {Algebra(NUMBER, 1): rdata, lhs:1})
  106. return lhs
  107. if rhead is TERM_COEFF:
  108. term, coeff = rdata
  109. if term==lhs:
  110. return term_coeff_new(Algebra, (term, coeff+1))
  111. return Algebra(TERM_COEFF_DICT, {term: coeff, lhs:1})
  112. if rhead is TERM_COEFF_DICT:
  113. d = rdata.copy()
  114. term_coeff_dict_add_item(Algebra, d, lhs, 1)
  115. return term_coeff_dict_new(Algebra, d)
  116. if rhead is POW or rhead is BASE_EXP_DICT:
  117. return Algebra(TERM_COEFF_DICT, {lhs:1, rhs:1})
  118. else:
  119. if rhead is TERM_COEFF_DICT or rhead is EXP_COEFF_DICT:
  120. rhs = rhs.to(ADD)
  121. rhead, rdata = rhs.pair
  122. if rhead is ADD:
  123. data = [lhs] + rdata
  124. else:
  125. data = [lhs, rhs]
  126. return add_new(Algebra, [lhs, rhs])
  127. return super(type(self), self).algebra_add(Algebra, lhs, rhs, inplace)
  128. else:
  129. if rhead is TERM_COEFF_DICT or rhead is EXP_COEFF_DICT:
  130. rhs = rhs,to(ADD)
  131. rhead, rdata = rhs.pair
  132. if rhead is ADD:
  133. data = [lhs] + rdata
  134. else:
  135. data = [lhs, rhs]
  136. if Algebra.algebra_options.get('evaluate_addition'):
  137. ADD.combine_add_list(Algebra, data)
  138. return add_new(Algebra, data)
  139. def algebra_mul_number(self, Algebra, lhs, rhs, inplace):
  140. if Algebra.algebra_options.get('evaluate_addition'):
  141. return term_coeff_new(Algebra, (lhs, rhs))
  142. return mul_new(Algebra, [lhs, Algebra(NUMBER, rhs)])
  143. def algebra_mul(self, Algebra, lhs, rhs, inplace):
  144. if Algebra.algebra_options.get('is_additive_group'):
  145. if Algebra.algebra_options.get('evaluate_addition'):
  146. rhead, rdata = rhs.pair
  147. if rhead is NUMBER:
  148. return term_coeff_new(Algebra, (lhs, rdata))
  149. else:
  150. return mul_new(Algebra, [lhs, rhs])
  151. if Algebra.algebra_options.get('is_multiplicative_group'):
  152. if Algebra.algebra_options.get('evaluate_multiplication'):
  153. rhead, rdata = rhs.pair
  154. if Algebra.algebra_options.get('is_multiplicative_group_commutative'):
  155. if rhead is MUL or EXP_COEFF_DICT:
  156. rhs = rhead.to_BASE_EXP_DICT(Algebra, rdata, rhs)
  157. rhead, rdata = rhs.pair
  158. if rhead is NUMBER:
  159. return term_coeff_new(Algebra, (lhs, rdata))
  160. if rhead is BASE_EXP_DICT:
  161. data = rdata.copy()
  162. base_exp_dict_add_item(Algebra, data, lhs, 1)
  163. return base_exp_dict_new(Algebra, data)
  164. if lhs==rhs:
  165. return Algebra(POW, (lhs, 2))
  166. return Algebra(BASE_EXP_DICT, {lhs:1, rhs:1})
  167. else:
  168. if rhead is MUL:
  169. data = [lhs] + rdata
  170. else:
  171. data = [lhs, rhs]
  172. coeff = MUL.combine_mul_list(Algebra, data)
  173. assert coeff is 1,`coeff`
  174. return mul_new(Algebra, data)
  175. else:
  176. pass
  177. return super(type(self), self).algebra_mul(Algebra, lhs, rhs, inplace)
  178. def algebra_pow_number(self, Algebra, lhs, rhs, inplace):
  179. if Algebra.algebra_options.get('is_multiplicative_group'):
  180. if Algebra.algebra_options.get('evaluate_multiplication'):
  181. if Algebra.algebra_options.get('is_multiplicative_group_commutative'):
  182. return pow_new(Algebra, (lhs, rhs))
  183. else:
  184. return pow_new(Algebra, (lhs, rhs))
  185. else:
  186. return cls(POW, (lhs, rhs))
  187. return super(type(self), self).algebra_pow_number(Algebra, lhs, rhs, inplace)
  188. SYMBOL = SymbolHead()