payne
payne

Reputation: 14177

How to do interval arithmetic on sympy 1.3?

How do I do interval arithmetic in Sympy 1.3? (specifically, addition and multiplication)

For example, given:

q1 = Interval(0,255)
q2 = Interval(0,255)

The addition of those two intervals should be Interval(0, 510). (The plus operator is overloaded to mean "union", so q1+q2 yields Interval(0,255).)

If I try Add(q1, q2), I get an exception:

  Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/cache.py", line 93, in wrapper
    retval = cfunc(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/compatibility.py", line 850, in wrapper
    result = user_function(*args, **kwds)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/operations.py", line 45, in __new__
    c_part, nc_part, order_symbols = cls.flatten(args)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/add.py", line 223, in flatten
    newseq.append(Mul(c, s))
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/cache.py", line 93, in wrapper
    retval = cfunc(*args, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/compatibility.py", line 850, in wrapper
    result = user_function(*args, **kwds)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/operations.py", line 45, in __new__
    c_part, nc_part, order_symbols = cls.flatten(args)
  File "/usr/local/lib/python2.7/dist-packages/sympy/core/mul.py", line 186, in flatten
    r, b = b.as_coeff_Mul()
AttributeError: 'Interval' object has no attribute 'as_coeff_Mul'

(I get a similar exception for Mul).

Yet, the code to add two intervals seems to be right here: https://github.com/sympy/sympy/blob/sympy-1.3/sympy/sets/handlers/add.py#L22

But the dispatcher mechanism doesn't seem to be catching the case of Interval + Interval.

How do I do addition and multiplication on intervals in sympy?

Upvotes: 3

Views: 908

Answers (2)

user6655984
user6655984

Reputation:

In addition to SetExpr(Interval(...)) you can also use AccumBounds which is older and was originally intended to give answers to "find the limit of f" where f is an oscillating function. As far as arithmetics is concerned it works about the same:

AccumBounds(3, 5) + AccumBounds(2, 8)  #  AccumBounds(5, 13)
AccumBounds(-2, 5) * AccumBounds(2, 8)  #  AccumBounds(-16, 40)

but there are some interval computations where the implementation of AccumBounds is more complete.

sin(AccumBounds(0, 3))  #  AccumBounds(0, 1)
sin(SetExpr(Interval(0, 3)))  #  SetExpr(ImageSet(Lambda(x, sin(x)), Interval(0, 3)))

Upvotes: 2

user2357112
user2357112

Reputation: 280301

Sympy Intervals do not perform interval arithmetic. The function you found in the repository is one of the handlers for sympy.sets.setexpr.SetExpr, an expression type that takes values in a given set:

from sympy import Interval
from sympy.sets.setexpr import SetExpr

q1 = SetExpr(Interval(0, 255))
q2 = SetExpr(Interval(0, 255))

result = q1 + q2

SetExpr is currently hidden-ish and mostly undocumented.

Upvotes: 3

Related Questions