图片解析应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

79 lines
1.8 KiB

  1. from sympy.core import Basic, Expr
  2. from sympy.core.numbers import oo
  3. from sympy.core.symbol import symbols
  4. from sympy.multipledispatch import Dispatcher
  5. from sympy.sets.setexpr import set_mul
  6. from sympy.sets.sets import Interval, Set
  7. _x, _y = symbols("x y")
  8. _set_mul = Dispatcher('_set_mul')
  9. _set_div = Dispatcher('_set_div')
  10. @_set_mul.register(Basic, Basic)
  11. def _(x, y):
  12. return None
  13. @_set_mul.register(Set, Set)
  14. def _(x, y):
  15. return None
  16. @_set_mul.register(Expr, Expr)
  17. def _(x, y):
  18. return x*y
  19. @_set_mul.register(Interval, Interval)
  20. def _(x, y):
  21. """
  22. Multiplications in interval arithmetic
  23. https://en.wikipedia.org/wiki/Interval_arithmetic
  24. """
  25. # TODO: some intervals containing 0 and oo will fail as 0*oo returns nan.
  26. comvals = (
  27. (x.start * y.start, bool(x.left_open or y.left_open)),
  28. (x.start * y.end, bool(x.left_open or y.right_open)),
  29. (x.end * y.start, bool(x.right_open or y.left_open)),
  30. (x.end * y.end, bool(x.right_open or y.right_open)),
  31. )
  32. # TODO: handle symbolic intervals
  33. minval, minopen = min(comvals)
  34. maxval, maxopen = max(comvals)
  35. return Interval(
  36. minval,
  37. maxval,
  38. minopen,
  39. maxopen
  40. )
  41. @_set_div.register(Basic, Basic)
  42. def _(x, y):
  43. return None
  44. @_set_div.register(Expr, Expr)
  45. def _(x, y):
  46. return x/y
  47. @_set_div.register(Set, Set)
  48. def _(x, y):
  49. return None
  50. @_set_div.register(Interval, Interval)
  51. def _(x, y):
  52. """
  53. Divisions in interval arithmetic
  54. https://en.wikipedia.org/wiki/Interval_arithmetic
  55. """
  56. if (y.start*y.end).is_negative:
  57. return Interval(-oo, oo)
  58. if y.start == 0:
  59. s2 = oo
  60. else:
  61. s2 = 1/y.start
  62. if y.end == 0:
  63. s1 = -oo
  64. else:
  65. s1 = 1/y.end
  66. return set_mul(x, Interval(s1, s2, y.right_open, y.left_open))