So the issue here is that SymPy uses an internal cache, which means
that sometimes two equal objects will also be equal in memory. The
second time you called Symbol, the first Symbol('x') was found in the
cache and returned. This keeps only one Symbol('x') object in memory
at a time. Jason's example of a = 1; b = 1 is similar, because Python
itself caches small integers.
SymPy objects are immutable, so it is free to replace two equal
objects by the same object. Practically this means that two
Symbol('x') objects are always the same, so you are free to reuse the
same x as before, or to make a new one. Symbols are compared only by
name and assumptions, so if those are equal, they will be the same.
You should never rely on "is" comparson for SymPy objects (with the
exception of singletonized classes, which are the things on the S
object). Always use == to see if two things are the same.
> Has this behaviour changed since a previous version? I am sure that I had an
> issue where I had an expression e.g. f=x**2 and differentiating w.r.t a newly
> created symbol by the name "x" gave zero, because it was not the same "x".
> (This works as expected in recent versions and gives f.diff(x) == 2*x, so I
> can't reproduce this half-remembered claimed behaviour.)
The issue was most likely due to assumptions. If two symbols have the
same name but different assumptions, they will be unequal:
>>> x = Symbol('x')
>>> x_positive = Symbol('x', positive=True)
>>> diff(x**2, x_positive)
0
>>> x == x_positive
False
If you use assumptions, it is good practice to always use the same
assumptions for any given symbol name. It also helps to design your
code so that you pass the same symbols around so that they end up
being the same.
Aaron Meurer
On Wed, Jun 3, 2020 at 4:48 PM James Bateman <[email protected]> wrote:
>
> Looks like I did indeed miss the deliberate mistake. Sorry for being an
> idiot and thank you for taking the time.
>
> For clarity, here is what I intended to post:
>
> import sympy as sp
> x = sp.Symbol('x')
> y = sp.Symbol('x') # deliberate mistake here
> x == y # True
> x is y # True
>
> I'm aware of Python names not being accessible through introspection. It
> still seems as though two calls to "Symbol('x')" should create two distinct
> instances of a SymPy symbol, which just happen to share the name. However, I
> see the sense in comparing symbols by name.
>
> Has this behaviour changed since a previous version? I am sure that I had an
> issue where I had an expression e.g. f=x**2 and differentiating w.r.t a newly
> created symbol by the name "x" gave zero, because it was not the same "x".
> (This works as expected in recent versions and gives f.diff(x) == 2*x, so I
> can't reproduce this half-remembered claimed behaviour.)
>
>
> On Wednesday, June 3, 2020 at 11:30:31 PM UTC+1, Oscar wrote:
>>
>> >> >> On Wed, Jun 3, 2020 at 12:53 PM James Bateman <[email protected]>
>> >> >> wrote:
>> >> >>>
>> >> >>> I've just discovered a bug in my code which boiled down to the
>> >> >>> following, where a symbol "y" was given the same SymPy name as an
>> >> >>> existing symbol.
>> >> >>>
>> >> >>> import sympy as sp
>> >> >>> x = sp.Symbol('x')
>> >> >>> y = sp.Symbol('y')
>> >> >>>
>> >> >>> x == y # True
>> >> >>> x is y # True; expected False
>> >> >>> x + y # 2*x; expected x + x (which would have made the bug in my code
>> >> >>> more apparent)
>>
>> On Wed, 3 Jun 2020 at 23:18, James Bateman <[email protected]> wrote:
>> >
>> > Thank you, but I don't need help debugging my code; I had a typo which
>> > boiled down to the example I gave. My only question was whether this was
>> > intended behaviour.
>> >
>> > Please note the deliberate mistake of "y = Symbol('x')", which you may
>> > have missed when interpreting my question. True is returned for both "x
>> > == y" and "x is y" in SymPy 1.2 (local installation) and SymPy 1.5.1
>> > (http://live.sympy.org).
>>
>> I think you maybe forgot to make the deliberate mistake when posting
>> here (see above).
>>
>> The name of the Python variable does not need to match the name of the
>> symbol. Sympy has no way of knowing what name you use for the Python
>> variable so if you do
>>
>> x = Symbol('y')
>>
>> then there is no way for sympy to know that you assigned the result to
>> a variable called x. That's not so much an intended feature but just
>> how Python works.
>>
>> Symbols with the same name (and assumptions) as considered equivalent
>> in sympy which is useful in many situations. If you want to create a
>> symbol that will only ever compare equal to itself regardless of the
>> name of any other symbol then you can use Dummy:
>> https://docs.sympy.org/latest/modules/core.html#dummy
>>
>> Dummy is a bit awkward to use in some situations which is why it isn't
>> the default behaviour for symbols in sympy.
>>
>> --
>> Oscar
>
> --
> 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 [email protected].
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/sympy/c915ba41-ee86-404e-af07-689f5e89d174%40googlegroups.com.
--
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 [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/sympy/CAKgW%3D6Ldc5tvhcOf2V9pvya7LMBK36YYXzSFG8obxA%2BZ5T2_Ug%40mail.gmail.com.