what does S(0) mean?

110 views
Skip to first unread message

Christoph Kukulies

unread,
Mar 20, 2015, 1:57:27 PM3/20/15
to sy...@googlegroups.com
Hi,

I'm playing a bit with sympy and reduce_inequations while I'm stumbling about understanding a term:

from sympy import Q, sympify as S
from sympy.abc import x, y
from sympy.solvers.inequalities import reduce_inequalities
reduce_inequalities(S(0) <= x + 3, Q.real(x), [])

What does S(0) mean hetre exactly? print S(0) gives me 0, so why not just 0 and why S(0)?

Christoph

Francesco Bonazzi

unread,
Mar 20, 2015, 2:05:04 PM3/20/15
to sy...@googlegroups.com
S(0) is SymPy's zero, 0 is python's zero.

SymPy integers form fractions under division, Python integers become floating-point numbers.

Sudhanshu Mishra

unread,
Mar 20, 2015, 2:12:17 PM3/20/15
to sy...@googlegroups.com

Hi

It gives sympyfied 0. Its different from Python's integer object.

Regards
Sudhanshu Mishra


--
You received this message because you are subscribed to the Google Groups "sympy" group.
To unsubscribe from this group and stop receiving emails from it, send an email to sympy+un...@googlegroups.com.
To post to this group, send email to sy...@googlegroups.com.
Visit this group at http://groups.google.com/group/sympy.
To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/3bc84e41-1f41-42f6-bc0b-4f0501c62960%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Aaron Meurer

unread,
Mar 20, 2015, 2:13:12 PM3/20/15
to sy...@googlegroups.com
The S() function converts objects into SymPy objects, so S(0) converts
int(0) to sympy.Integer(0). It is completely redundant in this case,
as the 0 would be coerced automatically from the <= with the SymPy
expression x + 3. The S() function is typically only needed when
dividing integers, like S(1)/2, as 1/2 would be entirely Python, and
give a floating point number (or worse, in Python 2, integer
division). See http://docs.sympy.org/latest/tutorial/gotchas.html#two-final-notes-and
for more information about this.

Aaron Meurer

Christoph Kukulies

unread,
Mar 21, 2015, 4:45:11 AM3/21/15
to sy...@googlegroups.com


Am Freitag, 20. März 2015 19:13:12 UTC+1 schrieb Aaron Meurer:
The S() function converts objects into SymPy objects, so S(0) converts
int(0) to sympy.Integer(0). It is completely redundant in this case,


So you say one would better write 0 in the example? Wouldn't it then lead to better readability
when the authors of http://docs.sympy.org/0.7.5/modules/solvers/inequalities.html
use the 0 instead S(0).
 
as the 0 would be coerced automatically from the <= with the SymPy
expression x + 3. The S() function is typically only needed when
dividing integers, like S(1)/2, as 1/2 would be entirely Python, and
give a floating point number (or worse, in Python 2, integer
division). See http://docs.sympy.org/latest/tutorial/gotchas.html#two-final-notes-and
for more information about this.

Aaron Meurer

On Fri, Mar 20, 2015 at 11:56 AM, Christoph Kukulies
<ku...@physik.rwth-aachen.de> wrote:
> Hi,
>
> I'm playing a bit with sympy and reduce_inequations while I'm stumbling
> about understanding a term:
>
> from sympy import Q, sympify as S
> from sympy.abc import x, y
> from sympy.solvers.inequalities import reduce_inequalities
> reduce_inequalities(S(0) <= x + 3, Q.real(x), [])
>
> What does S(0) mean here exactly? print S(0) gives me 0, so why not just 0

corrected typo that was in my OP  (here)
 
> and why S(0)?
>
Christoph


Joachim Durchholz

unread,
Mar 21, 2015, 5:16:24 AM3/21/15
to sy...@googlegroups.com
Am 21.03.2015 um 09:45 schrieb Christoph Kukulies:
>
>
> Am Freitag, 20. März 2015 19:13:12 UTC+1 schrieb Aaron Meurer:
>>
>> The S() function converts objects into SymPy objects, so S(0) converts
>> int(0) to sympy.Integer(0). It is completely redundant in this case,
>
> So you say one would better write 0 in the example? Wouldn't it then lead
> to better readability
> when the authors of
> http://docs.sympy.org/0.7.5/modules/solvers/inequalities.html
> use the 0 instead S(0).

On that page, S(0) is actually required.

Aaron Meurer

unread,
Mar 21, 2015, 3:05:34 PM3/21/15
to sy...@googlegroups.com
https://github.com/sympy/sympy/pull/9181

Aaron Meurer

On Sat, Mar 21, 2015 at 3:45 AM, Christoph Kukulies
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/596c6d8f-42c2-4f25-b1e9-c471dfc491e5%40googlegroups.com.

Joachim Durchholz

unread,
Mar 22, 2015, 5:31:24 AM3/22/15
to sy...@googlegroups.com
Am 21.03.2015 um 20:05 schrieb Aaron Meurer:
> https://github.com/sympy/sympy/pull/9181

I see, S(0) is not necessary after all.

I stand corrected, but how does this work?

It is doing

> 0 <= x + 3

which evaluates to

> 0 <= Add(Symbol: x, Integer: 3)

and then calls the __le__ of Add.
However, in the Python docs, it says

> a <= b is equivalent to a.__le__(b)

so I'd have expected it to go into

0.__le__(Add(...))

and try a numeric comparison.

Does SymPy install its own __le__ on int? (Technically possible but I'd
be shocked.)
Is Python's int.__le__ checking the other operator's type and calling
into it? (If yes, is there a reference to that behaviour, or is it a
CPython implementation detail?)

I'm confused...

Aaron Meurer

unread,
Mar 22, 2015, 5:24:12 PM3/22/15
to sy...@googlegroups.com
Python operations fallback to the reverse operation when they are not
defined, so e.g., x + y does x.__add__(y) and if that returns
NotImplemented, it does y.__radd__(x). For the comparison operators,
it does the flipped operator, so this would be (0).__le__(x + 3),
which returns NotImplemented, so it then calls (x + 3).__ge__(0),
which works. The only downside here is that you end up getting
inequality in the reversed order from what you wanted.

Aaron Meurer
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/550E8BE8.5050104%40durchholz.org.

Joachim Durchholz

unread,
Mar 22, 2015, 6:16:25 PM3/22/15
to sy...@googlegroups.com
Am 22.03.2015 um 22:23 schrieb Aaron Meurer:
> Python operations fallback to the reverse operation when they are not
> defined, so e.g., x + y does x.__add__(y) and if that returns
> NotImplemented, it does y.__radd__(x). For the comparison operators,
> it does the flipped operator, so this would be (0).__le__(x + 3),
> which returns NotImplemented, so it then calls (x + 3).__ge__(0),
> which works.

Good to know - I was suspecting that that's the case, but wasn't 100% sure.
Is this behaviour documented somewhere? I didn't find any reference to
it, but maybe I'm looking in the wrong spots.

> The only downside here is that you end up getting
> inequality in the reversed order from what you wanted.

No big deal as long as all comparison functions are implemented
consistently, I suppose.
Do I suppose correctly?

Ah, one trap: Consistency has to be ensured across classes. Not
difficult but requires diligence and quite precise knowledge about
Python's comparison semantics.
Any other traps?

Aaron Meurer

unread,
Mar 22, 2015, 7:30:09 PM3/22/15
to sy...@googlegroups.com
On Sun, Mar 22, 2015 at 5:16 PM, Joachim Durchholz <j...@durchholz.org> wrote:
> Am 22.03.2015 um 22:23 schrieb Aaron Meurer:
>>
>> Python operations fallback to the reverse operation when they are not
>> defined, so e.g., x + y does x.__add__(y) and if that returns
>> NotImplemented, it does y.__radd__(x). For the comparison operators,
>> it does the flipped operator, so this would be (0).__le__(x + 3),
>> which returns NotImplemented, so it then calls (x + 3).__ge__(0),
>> which works.
>
>
> Good to know - I was suspecting that that's the case, but wasn't 100% sure.
> Is this behaviour documented somewhere? I didn't find any reference to it,
> but maybe I'm looking in the wrong spots.

https://docs.python.org/3/reference/datamodel.html#object.__lt__. That
page in general is a good reference for all these sorts of things.

Aaron Meurer

>
>> The only downside here is that you end up getting
>>
>> inequality in the reversed order from what you wanted.
>
>
> No big deal as long as all comparison functions are implemented
> consistently, I suppose.
> Do I suppose correctly?
>
> Ah, one trap: Consistency has to be ensured across classes. Not difficult
> but requires diligence and quite precise knowledge about Python's comparison
> semantics.
> Any other traps?
>
> --
> You received this message because you are subscribed to the Google Groups
> "sympy" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sympy+un...@googlegroups.com.
> To post to this group, send email to sy...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sympy.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/550F3F36.7090109%40durchholz.org.

Joachim Durchholz

unread,
Mar 23, 2015, 3:05:02 AM3/23/15
to sy...@googlegroups.com
Am 23.03.2015 um 00:29 schrieb Aaron Meurer:
> https://docs.python.org/3/reference/datamodel.html#object.__lt__. That
> page in general is a good reference for all these sorts of things.

Aaah... I've been turning to the 2.7 docs so I don't accidentally do
anything 3.x, and the NotImplemented detail isn't documented in the 2.7
version of datamodel.html.
Reply all
Reply to author
Forward
0 new messages