On Wed, Jun 3, 2020 at 4:55 PM Aaron Meurer <asmeu...@gmail.com> wrote: > > 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:
And to clarify, this behavior is not new. Symbol equality has worked like this for a very long time. Aaron Meurer > > >>> 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 <james.bate...@gmail.com> 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 <james....@gmail.com> > >> >> >> 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 <james....@gmail.com> 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 sympy+unsubscr...@googlegroups.com. > > 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 sympy+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/sympy/CAKgW%3D6Jk3fcvts_x3Cri-Fek0GcPmw0_DpW9pi0ObyxYHRO8-Q%40mail.gmail.com.