dop.py 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. #Copyright (c) 2008, Riccardo De Maria
  2. #All rights reserved.
  3. from .pol import pol, normder
  4. from .polmap import polmap
  5. class dop(pol):
  6. def __init__(self,val=None,order=None,eps=1E-13,loc={},m='eval'):
  7. self.coef={}
  8. self.vars=[]
  9. self.order=1000
  10. self.eps=eps
  11. if val!=None:
  12. if isinstance(val,dop):
  13. self.coef.update(val.coef)
  14. self.vars=val.vars[:]
  15. self.order=val.order
  16. self.eps=val.eps
  17. elif isinstance(val,str):
  18. if m=='eval':
  19. c=compile(val,'eval','eval')
  20. l=dict( (i,dop(i,m='name')) for i in c.co_names)
  21. l.update(loc)
  22. dop.__init__(self,eval(c,{},l))
  23. elif m=='name':
  24. self.vars=[val]
  25. self.coef[(1,)]=pol(1.)
  26. if order is not None:
  27. self.order=order
  28. def _derpol(self,other):
  29. new=pol(order=min(self.order,other.order))
  30. new.vars=list(set(other.vars+self.vars))
  31. for i in self.coef:
  32. for j in other:
  33. c=self.coef[i]*other[j]
  34. expi=dict(zip(self.vars,i))
  35. expj=dict(zip(other.vars,j))
  36. newexp=tuple([-expi.get(k,0)+expj.get(k,0) for k in new.vars])
  37. for k in self.vars:
  38. c*=normder(expj.get(k,0), expi.get(k,0))
  39. new[newexp]=new.get(newexp,0.)+c
  40. return new.truncate().dropneg()
  41. def __call__(self,other):
  42. if isinstance(other,pol):
  43. return self._derpol(other)
  44. elif isinstance(other,polmap):
  45. m=polmap(other)
  46. for n,v in m.items():
  47. m[n]=self(v)
  48. return m
  49. # def truncate(self):
  50. # return self
  51. def pop(h,vars):
  52. h=pol(h)
  53. vars=list(vars)
  54. out=0
  55. while vars:
  56. x=vars.pop(0)
  57. p=vars.pop(0)
  58. out+=dop(x)*(-dop(p)(h))+dop(p)*dop(x)(h)
  59. return out