Hello,

I appreciate your patience in explaining my issue. Checking dimensions in 
Sympy is useful for my work, so I am seeking to implement the check 
correctly.
I understand what you're saying about Python variables versus Sympy 
Symbols.  There are two examples in my response below. The first ("Example 
1") is an attempt to use the substitution-based approach.  In Example 2 I 
realized I could reduce my issue to three lines (which exclude irrelevant 
aspects of Latex and Python variables). 

Example 1 using latex to Sympy to dimensions
Here's what I get when I use substitution of dimensions:
>>> import sys
>>> sys.version
'3.6.9 (default, Apr 18 2020, 01:56:04) \n[GCC 8.4.0]'
>>> import sympy
>>> 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

Define the expression in Latex, then convert to Sympy expression
>>> eq = parse_latex("F = m a")
>>> F, m, a = sympy.symbols('F m a')
These three on the left side are Python variables

For each Sympy symbol in eq, replace with the Sympy dimensions
>>> eq.subs({F: mass*length/time**2, m: mass, a: length/time**2})
False
That boolean return wasn't what I was aiming for, so below I break the 
process down

Separate substitution into two steps and review the output
>>> eq.lhs.subs({F: mass*length/time**2, m: mass, a: length/time**2})
Dimension(length*mass/time**2)
>>> eq.rhs.subs({F: mass*length/time**2, m: mass, a: length/time**2})
Dimension(length/time**2)*Dimension(mass, M)

Now that I have confidence the Sympy substitution is behaving as expected, 
save the results to two Python variables
>>> RHS = eq.rhs.subs({F: mass*length/time**2, m: mass, a: length/time**2})
>>> RHS
Dimension(length/time**2)*Dimension(mass, M)
>>> type(RHS)
<class 'sympy.core.mul.Mul'>
That Mul is potentially the cause of my issue with dimsys_SI.equivalent_dims 
below. If there is a way to simplify the Mul of Dimension class objects, 
that would probably eliminate the issue.

The left-hand side of eq returns a Dimension class object
>>> LHS = eq.lhs.subs({F: mass*length/time**2, m: mass, a: length/time**2})
>>> LHS
Dimension(length*mass/time**2)
>>> type(LHS)
<class 'sympy.physics.units.dimensions.Dimension'>

The issue of failing to compare the left-side dimensions and the right-side 
dimensions could be due to the Mul, but I do not know how to simplify RHS. 
Or I may be incorrectly supplying Python variables LHS and RHS
>>> dimsys_SI.equivalent_dims( RHS, LHS )
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 454, in equivalent_dims
    deps1 = self.get_dimensional_dependencies(dim1)
  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'

After writing my example 1, I realized there is a simpler example of the 
issue.

Example 2: the short version

>>> import sys
>>> sys.version
'3.6.9 (default, Apr 18 2020, 01:56:04) \n[GCC 8.4.0]'
>>> import sympy
>>> sympy.__version__
'1.7.dev'
>>> from sympy.physics.units import mass, length
>>> from sympy.physics.units.systems.si import dimsys_SI
>>> sympy.Mul(mass, length)
Dimension(length, L)*Dimension(mass, M)
>>> mass*length
Dimension(length*mass)
The above two lines appear equivalent but not equal

Same issue as in Example 1,
>>> dimsys_SI.equivalent_dims( sympy.Mul(mass, length), mass*length )
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/sympy/physics/units/dimensions.py", line 461, in 
equivalent_dims
    deps1 = self.get_dimensional_dependencies(dim1)
  File "/opt/sympy/physics/units/dimensions.py", line 455, in 
get_dimensional_dependencies
    dimdep = self._get_dimensional_dependencies_for_name(name)
  File "/opt/sympy/physics/units/dimensions.py", line 429, in 
_get_dimensional_dependencies_for_name
    for k, v in d.items():
AttributeError: 'NoneType' object has no attribute 'items'

I think the reason is the Mul. However, I do not know how to simplify to 
Dimension
>>> type(mass*length)
<class 'sympy.physics.units.dimensions.Dimension'>
>>> type(sympy.Mul(mass, length))
<class 'sympy.core.mul.Mul'>
>>> sympy.simplify(sympy.Mul(mass, length))
Dimension(length, L)*Dimension(mass, M)


Kindly,

Ben

On Tuesday, June 2, 2020 at 11:46:41 AM UTC-4, Aaron Meurer wrote:
>
> 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 
>
>

-- 
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/993a7df4-b126-4ba1-8859-cd7000c2d3bc%40googlegroups.com.

Reply via email to