Kano001's picture
Upload 3077 files
6a86ad5 verified
raw
history blame
1.84 kB
from sympy.core import Basic, Expr
from sympy.core.numbers import oo
from sympy.core.symbol import symbols
from sympy.multipledispatch import Dispatcher
from sympy.sets.setexpr import set_mul
from sympy.sets.sets import Interval, Set
_x, _y = symbols("x y")
_set_mul = Dispatcher('_set_mul')
_set_div = Dispatcher('_set_div')
@_set_mul.register(Basic, Basic)
def _(x, y):
return None
@_set_mul.register(Set, Set)
def _(x, y):
return None
@_set_mul.register(Expr, Expr)
def _(x, y):
return x*y
@_set_mul.register(Interval, Interval)
def _(x, y):
"""
Multiplications in interval arithmetic
https://en.wikipedia.org/wiki/Interval_arithmetic
"""
# TODO: some intervals containing 0 and oo will fail as 0*oo returns nan.
comvals = (
(x.start * y.start, bool(x.left_open or y.left_open)),
(x.start * y.end, bool(x.left_open or y.right_open)),
(x.end * y.start, bool(x.right_open or y.left_open)),
(x.end * y.end, bool(x.right_open or y.right_open)),
)
# TODO: handle symbolic intervals
minval, minopen = min(comvals)
maxval, maxopen = max(comvals)
return Interval(
minval,
maxval,
minopen,
maxopen
)
@_set_div.register(Basic, Basic)
def _(x, y):
return None
@_set_div.register(Expr, Expr)
def _(x, y):
return x/y
@_set_div.register(Set, Set)
def _(x, y):
return None
@_set_div.register(Interval, Interval)
def _(x, y):
"""
Divisions in interval arithmetic
https://en.wikipedia.org/wiki/Interval_arithmetic
"""
if (y.start*y.end).is_negative:
return Interval(-oo, oo)
if y.start == 0:
s2 = oo
else:
s2 = 1/y.start
if y.end == 0:
s1 = -oo
else:
s1 = 1/y.end
return set_mul(x, Interval(s1, s2, y.right_open, y.left_open))