ilmorez ilmorez - 11 months ago 48
Python Question

Possible incongruence in Sympy when assuming positive numbers

Using Sympy package version 1.0 on Python 2.7.11 I found what (to me) is an incongruence. This is the code I'm using:

import sympy as sy
from sympy.stats import Normal, density
from sympy.assumptions import assuming, Q, ask


a = sy.symbols('a', real=True)
with assuming(Q.positive(a)):
print ask(Q.positive(a))
N = Normal('N', 0, a)

What I got is


from the first print as expected but an exception when creating the Normal object

ValueError: Standard deviation must be positive

Can anyone, please, explain if it is intended to be like this and why? Thanks!

PS: I'm aware that I could declare the symbols to be positive


The problem is simple: there are two assumptions systems in SymPy, called the old-style and new-style assumptions. They don't interact quite well, yet.

The old-style assumptions define predicates on symbols, e.g.

x = Symbol("x", positive=True)

deduction is then performed on generic expressions with methods such as .is_positive

>>> x.is_positive

The latest version of SymPy has linked the old-style assumptions to the new-style ones, so you can now query

>>> ask(Q.positive(x))

Older versions of SymPy would return None, as the two assumptions systems were not linked at all.

The problem is that this relation is not yet reciprocal: the old-style assumptions system is not aware of assumptions defined with the new-style assumptions system. You can verify it yourself:

>>> with assuming(Q.positive(y)):
...    print y.is_positive    

The random variable Normal requires the standard deviation parameter to be positive, verification is done with the old-style assumptions. Therefore your case fails.

Note that the positivity condition on the standard deviation is likely to get relaxed to a non-negativity condition in the next SymPy version (that is, allow the positivity-indefinite case to be accepted).