SymPy: How can I check, if symbol is a constant or a variable?
Asked Answered
L

2

6

In sympy, I want to create a constant e.g. to represent the speed of light. Thus I initialize c with the keyword constant=True.

Later I want to check, if a symbol is a constant or a variable. Unexpectedly the command c.is_constant() outputs False.

c = Symbol( 'c' , constant=True, real=True )
c.is_real       # outputs True as expected.
c.is_constant() # outputs False. This is unexpected !

How can I check, if a symbol is a constant or a variable ?

Lamasery answered 29/7, 2021 at 18:25 Comment(5)
SymPy already has a constant for the speed of light but it's also fine to use an ordinary symbol. Why do you want to distinguish between a constant and a variable? What difference would it make? There is almost certainly a better way of solving your actual problem.Mallissa
Looking at the code/docs of is_constant I see that it does not check the assumptions. So setting that assumption as you do does not make a difference. From the docs it looks like is_constant makes more sense when applied to an expression than to a single symbol. Assumptions keywords are not constrained. foobar=True is allowed, but only means something if I add some sort of test.Smallage
@OscarBenjamin : I want to use the linearity of a function: f( const*x ) = const*f( x ), but I don't want to put something outside the brackets, if I face the product of two variables (NOT: f(yx)=y*f(x)). Thus I want to check, if x,y or const are constants or variables.Lamasery
@Smallage : Thanks for the hint that the is_constant property seems to be taylored for composite expressions! That makes sense to me! But I don't understand the SymPy's assumptions system, yet. Could you give me an example of how to give a symbol a custom boolean property like foobar and how to check for it using the assumption system you mentioned?Lamasery
I don't think that declaring a symbol to be a "constant" is a good way of doing whatever it is you are trying to do. I think you can get a better answer if you ask a question about your actual problem i.e. you want to do some sort of manipulation based on knowing that your function f commutes with multiplication by some symbols but not others.Mallissa
B
2

Instead of creating a Symbol, creating a Quantity object should do the job. The code example below does what you are trying to do.

from sympy.physics.units.quantities import Quantity

c = Quantity('c')
print(c.is_constant())

Output:

True

In case you need something else, or more customized, you may try doing something similar to what Sympy does for constant values such as e and pi, you can find the source code for that here:

https://github.com/sympy/sympy/blob/46e00feeef5204d896a2fbec65390bd4145c3902/sympy/core/numbers.py#L3421-L3578

And for more information on why the is_constant method was returning False, check out this

https://docs.sympy.org/latest/modules/core.html#sympy.core.expr.Expr.is_constant

Bethanybethe answered 29/7, 2021 at 19:42 Comment(2)
Thank you, Luis, this is a possibility to distinguish: variables = Symbols, constants = Quantities, BUT there is a drawback of using Quantities to me: It seems that equations containing Quantities are displayed uglily by IPython.core.display in Spyder's IPython console. A nice latex display of equations is important to me. Thus this is not a satisfactory option to me.Lamasery
In such case, you could try the other thing I mention, which is emulating what SymPy does for defining PI and E. Which is creating a class for your constant, like they do here: github.com/sympy/sympy/blob/…Smokedry
S
0

Look what happens when I construct a symbol with various keywords:

In [93]: c = Symbol( 'c' , constant=True, real=True, foobar=True )
In [94]: c._assumptions
Out[94]: 
{'constant': True,
 'real': True,
 'extended_real': True,
 'hermitian': True,
 'commutative': True,
 'imaginary': False,
 'finite': True,
 'complex': True,
 'infinite': False,
 'foobar': True}

Those keywords, plus some defaults, are put in a dict. I included your constant, and random choice of my own foobar. Neither has special meaning.

The is_constant method does not look for this assumption value:

def is_constant(self, *wrt, **flags):
    if not wrt:
        return False
    return not self in wrt

We have to study its docs to see what a wrt is.

Specifying an assumption is one thing, actually using it is quite another.

Smallage answered 1/8, 2021 at 6:41 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.