The issue here is you're confusing Python variables and SymPy symbols.
The use of eval() isn't helping, because eval() evaluates based on the
Python variables (I would try to avoid eval() if possible). See
https://docs.sympy.org/latest/tutorial/gotchas.html. Once you define
F, m, and a, they have no bearing on the symbols that are present in
eq. SymPy has no way to know that there are Python variables named F,
m, and a when looking at eq.
What you can do is
F, m, a = symbols('F m a')
eq.subs({F: mass*length/time**2, m: mass, a: length/time**2}).
to replace the symbols with units in the equation.
Aaron Meurer
On Thu, May 28, 2020 at 6:08 AM Ben <[email protected]> wrote:
>
> Good morning,
>
> To verify that the issue is not due to using an old version, I re-ran the
> same example with the current development version of SymPy.
>
> >>> import sys
> >>> sys.version
> '3.6.9 (default, Apr 18 2020, 01:56:04) \n[GCC 8.4.0]'
> >>> sympy.__version__
> '1.7.dev'
> >>> from sympy.physics.units import mass, length, time
> >>> from sympy.physics.units.systems.si import dimsys_SI
> >>> from sympy.parsing.latex import parse_latex
> >>> eq = parse_latex("F = m a")
> >>> F = mass * length / time**2
> >>> m = mass
> >>> a = length / time**2
> >>> dimsys_SI.equivalent_dims( eq.lhs, eq.rhs )
> False
> >>> dimsys_SI.equivalent_dims( eval(str(eq.lhs)), eval(str(eq.rhs)) )
> True
>
> Should I open an issue on github for this?
>
>
> On Wednesday, May 27, 2020 at 9:48:02 PM UTC-4, Ben wrote:
>>
>> I agree with your assessment.
>>
>> Here's my minimum working example where I don't use eval(str()) and get the
>> problem.
>> >>> import sys
>> >>> sys.version
>> '3.6.9 (default, Apr 18 2020, 01:56:04) \n[GCC 8.4.0]'
>> >>> import sympy
>> >>> sympy.__version__
>> '1.5.1'
>> >>> from sympy.physics.units import mass, length, time
>> >>> from sympy.physics.units.systems.si import dimsys_SI
>> >>> from sympy.parsing.latex import parse_latex
>> >>> eq = parse_latex("F = m a")
>> >>> F = mass * length / time**2
>> >>> m = mass
>> >>> a = length / time**2
>> >>> dimsys_SI.equivalent_dims( eq.lhs, eq.rhs )
>> False
>>
>> For context, here are the variables
>> >>> eq.lhs
>> F
>> >>> eq.rhs
>> a*m
>> >>> F
>> Dimension(length*mass/time**2)
>> >>> a
>> Dimension(length/time**2)
>> >>> a*m
>> Dimension(length*mass/time**2)
>> >>> m
>> Dimension(mass, M)
>>
>>
>> On Wednesday, May 27, 2020 at 8:59:42 PM UTC-4, Aaron Meurer wrote:
>>>
>>> Why are you using eval(str(eq.lhs))? That should just give back eq.lhs.
>>>
>>> Aaron Meurer
>>>
>>> On Wed, May 27, 2020 at 6:35 PM Ben <[email protected]> wrote:
>>> >
>>> > Thanks Aaron for your help.
>>> >
>>> > With your guidance, I solved my problem (though my use of eval() feels
>>> > hacky).
>>> >
>>> > >>> import sympy
>>> > >>> from sympy.physics.units import mass, length, time
>>> > >>> from sympy.physics.units.systems.si import dimsys_SI
>>> > >>> from sympy.parsing.latex import parse_latex
>>> > >>> eq = parse_latex("F = m a")
>>> > >>> F = mass * length / time**2
>>> > >>> m = mass
>>> > >>> a = length / time**2
>>> > >>> dimsys_SI.equivalent_dims( eval(str(eq.lhs)), eval(str(eq.rhs)) )
>>> > True
>>> >
>>> >
>>> > I used eval() rather than variable substitution
>>> > >>> Fdim = mass * length / time**2
>>> > >>> mdim = mass
>>> > >>> adim = length / time**2
>>> > >>> lhs_dim = eq.lhs.subs([(F, Fdim), (m, mdim), (a, adim)])
>>> > >>> rhs_dim = eq.rhs.subs([(F, Fdim), (m, mdim), (a, adim)])
>>> > because I was not able to figure out how to simplify the RHS
>>> > >>> rhs_dim
>>> > Dimension(length/time**2)*Dimension(mass, M)
>>> >
>>> > Even though the RHS dimensions simplify to be equivalent to the LHS, I
>>> > get an error when I compare the LHS and RHS:
>>> > >>> dimsys_SI.equivalent_dims( lhs_dim, rhs_dim )
>>> > Traceback (most recent call last):
>>> > File "<stdin>", line 1, in <module>
>>> > File
>>> > "/usr/local/lib/python3.6/dist-packages/sympy/physics/units/dimensions.py",
>>> > line 455, in equivalent_dims
>>> > deps2 = self.get_dimensional_dependencies(dim2)
>>> > File
>>> > "/usr/local/lib/python3.6/dist-packages/sympy/physics/units/dimensions.py",
>>> > line 448, in get_dimensional_dependencies
>>> > dimdep = self._get_dimensional_dependencies_for_name(name)
>>> > File
>>> > "/usr/local/lib/python3.6/dist-packages/sympy/physics/units/dimensions.py",
>>> > line 422, in _get_dimensional_dependencies_for_name
>>> > for k, v in d.items():
>>> > AttributeError: 'NoneType' object has no attribute 'items'
>>> >
>>> >
>>> > On Wednesday, May 27, 2020 at 7:01:02 PM UTC-4, Aaron Meurer wrote:
>>> >>
>>> >> You're right that you have to define the Python variable name to
>>> >> access F like that. See
>>> >> https://docs.sympy.org/latest/tutorial/gotchas.html.
>>> >>
>>> >> You can get all the symbols in an expression with eq.free_symbols. Or
>>> >> if you know the symbol is F you can just set
>>> >>
>>> >> F = symbols('F')
>>> >>
>>> >> since symbols with the same name are equal, so F will be the same as
>>> >> the symbol F in the expression from parse_latex.
>>> >>
>>> >> Aaron Meurer
>>> >>
>>> >> On Wed, May 27, 2020 at 2:37 PM Ben <[email protected]> wrote:
>>> >> >
>>> >> > Hello,
>>> >> >
>>> >> > I have a string written in Latex for which I know the dimensions of
>>> >> > each symbol. My goal is to validate the dimensional consistency of the
>>> >> > expression. I'm having trouble with substitution. For example,
>>> >> >
>>> >> > >>> from sympy.physics.units import mass, length, time
>>> >> > >>> from sympy.physics.units.systems.si import dimsys_SI
>>> >> > >>> from sympy.parsing.latex import parse_latex
>>> >> > >>> eq = parse_latex("F = m a")
>>> >> > >>> eq
>>> >> > Eq(F, a*m)
>>> >> >
>>> >> > I can get the symbols from that expression
>>> >> > >>> set_of_symbols_in_eq = eq.free_symbols
>>> >> >
>>> >> > And for each symbol in the set I know what dimensions each has:
>>> >> > >>> Fdim = mass * length / time**2
>>> >> > >>> mdim = mass
>>> >> > >>> adim = length / time**2
>>> >> >
>>> >> > When I try substituting the dimensions into the original expression, I
>>> >> > get an error
>>> >> > >>> eq.subs({F: Fdim, m: mdim, a: adim})
>>> >> > Traceback (most recent call last):
>>> >> > File "<stdin>", line 1, in <module>
>>> >> > NameError: name 'F' is not defined
>>> >> >
>>> >> > That is surprising, because F is a Symbol:
>>> >> > >>> eq.lhs
>>> >> > F
>>> >> > >>> type(eq.lhs)
>>> >> > <class 'sympy.core.symbol.Symbol'>
>>> >> >
>>> >> > I think that error means that although F is a Symbol, there isn't a
>>> >> > variable named F that points to the Symbol F?
>>> >> > If that's the case, I don't know how to access the symbols in the
>>> >> > abstract syntax tree provided by eq.
>>> >> > How would I indicate to SymPy that "F = m a" in eq has variables with
>>> >> > certain dimensions?
>>> >> >
>>> >> > My goal is to run
>>> >> > >>> dimsys_SI.equivalent_dims(Fdim, mdim * adim)
>>> >> > True
>>> >> > without retyping the expression.
>>> >> >
>>> >> > I think I want something like the following, except with dimensions
>>> >> > substituted for each symbol.
>>> >> > >>> dimsys_SI.equivalent_dims( eq.lhs, eq.rhs )
>>> >> > False
>>> >> >
>>> >> > --
>>> >> > 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/a4e2b3fe-27b2-45b8-a7f6-598caea772de%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/6e6c4358-7894-4099-9d27-74c5fefe2a31%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/35ed29bb-4bdf-4229-92a0-26b3b1449092%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%3D6%2BuDmtafE4QW-BaKL8K5_70YzckgwqYJRQM_ougP_fUmQ%40mail.gmail.com.