Home > Mobile >  How to create two different sympy symbols with the same name
How to create two different sympy symbols with the same name

Time:08-11

I'm trying to use the answer from this question and came across some interesting behaviour:

from sympy import Symbol


class MySymbol(Symbol):

    def __new__(cls, symbol, description):

        obj = super().__new__(cls, symbol)
        obj.description = description
        return obj


symbolx = MySymbol('x', 100)
symbolx2 = MySymbol('x', 200)
symboly = MySymbol('y', 300)

print(symbolx.description)
print(symbolx2.description)
print(symboly.description)

returns:

200
200
300

Instead of the expected

100
200
300

My best guess is that sympy returns the same Symbol for a given name. Is there any way to work around this?

CodePudding user response:

Based on @OscarBenjamin s comment, using Dummy rather than Symbol:

from sympy import Dummy

class MySymbol(Dummy):

    def __new__(cls, symbol, description):
        obj = super().__new__(cls, symbol)
        obj.description = description
        return obj


symbolx = MySymbol('x', 100)
symbolx2 = MySymbol('x', 200)
symboly = MySymbol('y', 300)

print(symbolx.description)
print(symbolx2.description)
print(symboly.description)

Returns:

100
200
300

CodePudding user response:

My suggestion would be to create a wrapper object instead of inheriting Symbol. This way you may store various data while still keeping all of the sympy functionality.

from sympy import Symbol, Add

symbols = []

class DescSymbol:
    def __init__(self, symbol, description):
        self.s = Symbol(symbol)
        self.description = description


symbolx = DescSymbol('x', 100)
symbolx2 = DescSymbol('x', 200)
symboly = DescSymbol('y', 300)

print(id(symbolx.s))
print(symbolx.description) # 100
print(id(symbolx2.s)) # same as symbolx.s
print(symbolx2.description) # 200
print(id(symboly.s)) # unique
print(symboly.description) # 300

CodePudding user response:

The solution I currently have is to append white space to the end of the symbol to ensure it's unique:

from sympy import Symbol

symbols = []

class MySymbol(Symbol):

    def __new__(cls, symbol, description):
        while symbol in symbols:
            symbol  = ' '
        symbols.append(symbol)
        obj = super().__new__(cls, symbol)
        obj.description = description
        return obj


symbolx = MySymbol('x', 100)
symbolx2 = MySymbol('x', 200)
symboly = MySymbol('y', 300)

print(symbolx.description)
print(symbolx2.description)
print(symboly.description)

This returns:

100
200
300

I'll keep the question open in case anyone comes along with a more elegant answer

  • Related