I’m trying to simplify some expressions of positive odd integers with sympy. But sympy refuses to expand
floor, making the simplification hard to proceed.
To be specific,
x is a positive odd integer (actually in my particular use case, the constraint is even stricter. But sympy can only do odd and positive, which is fine).
x // 2 should be always equal to
(x - 1) / 2. Example code here:
from sympy import Symbol, simplify x = Symbol('x', odd=True, positive=True) expr = x // 2 - (x - 1) / 2 print(simplify(expr))
-x/2 + floor(x/2) + 1/2. Ideally it should print
What I’ve tried so far:
(x - 1) // 2 - (x - 1) / 2. Turns out to be 0.
2 * (x // 2 - (x - 1) / 2). Gives me:
-x + 2*floor(x/2) + 1.
FLOORop by customizing the
measure. No luck.
sympy.core.evaluate(False)context when creating the expression. Nuh.
rational, and play with other function like
collect. Doesn’t work either.
EDIT: Wolfram alpha can do this.
I tried to look like the assumptions of
x along with some expressions. It surprises me that
(x - 1) / 2).is_integer returns None, which means unknown.
I’m running out of clues. I’m even looking for alternativese of sympy. Any ideas guys?
I fail to see why sympy can’t simplify that.
But, on another hand, I’ve discovered the existence of
odd parameter just now, with your question.
What I would have done, without the knowledge of
k = Symbol('k', positive=True, integer=True) x = 2*k-1 expr = x // 2 - (x - 1) / 2
Then, expr is 0, without even the need to simplify.
So, can’t say why you way doesn’t work (and why that
odd parameter exists if it is not used correctly to guess that
x-1 is even, and therefore
(x-1)/2 integer). But, in the meantime, my way of defining an odd integer
There is some reluctance to make too much automatic in SymPy, but this seems like a case that could be addressed (since
(x-1)/2 is simpler than
floor(x/2). Until then, however, you can run a replacement on your expression which makes this transformation for you.
Let’s define a preferred version of
def _floor(x): n, d = x.as_numer_denom() if d == 2: if n.is_odd: return (n - 1)/2 if n.is_even: return n/2 return floor(x)
When you have an expression with
floor that you want to evaluate, replace
>>> x = Symbol('x', odd=True) >>> eq=x // 2 - (x - 1) / 2 >>> eq.replace(floor, _floor) 0