将命名表达式的字符串转换为表达式本身



实际问题说明
我使用sympy定义了许多表达式,如

import sympy as sp
a, b = sp.symbols('a,b', real=True, positive=True)
Xcharles_YclassA_Zregion1 = 1.01 * a**1.01 * b**0.99
Xbob_YclassA_Zregion1 = 1.009999 * a**1.01 * b**0.99
Xbob_YclassA_Zregion2 = 1.009999 * a**1.01 * b**0.99000000001
...

所以我使用了表达式的名称来描述类别(例如,X)中的选项(例如,charles,bob)。

现在我想要一个函数,它接受两个字符串(例如,'Xcharles_YclassA_Zregion1''Xbob_YclassA_Zregion1'),并返回它的简化比率(在这个例子中,1.00000099009999),所以我可以快速检查"如何不同";它们是,就结果而言,而不是就写作方式而言。例如,2*aa*2对于我的目标是相同的。

我怎么能做到这一点?

指出:

  1. 为了简单起见,示例中的表达式是硬编码的。但在我的实际情况中,它们来自许多其他表达式和操作的序列。
  2. 并非所有类别的所有选项组合都存在。例如,Xcharles_YclassA_Zregion2可能不存在。实际上,如果我要为现有的表达式名称编写一个表,它将被稀疏地填充。我想重写我的代码使用dict来存储表可能解决我的问题。但是我必须为此修改很多代码。
  3. 除了我的目标的实际方面,我不知道Symbol(这是一个特定的类)和表达式之间是否有任何形式的区别。从我读到的资料(例如,这个)中,我没有得出结论。这种理解可能有助于解决这个问题。

TL;DR - What I tried

我的目标是

def verify_ratio(vstr1, vstr2):
"""Compare the result of two different computations of the same quantity"""
ratio = sp.N(sp.parsing.sympy_parser.parse_expr(vstr1)) / sp.parsing.sympy_parser.parse_expr(vstr2)
print(vstr1 + ' / ' + vstr2, '=', sp.N(ratio))
return

这不起作用。下面的代码显示了为什么

import sympy as sp
a, b = sp.symbols('a,b', real=True, positive=True)
expr2 = 1.01 * a**1.01 * b**0.99
print(type(expr2), '->', expr2)

expr2b = sp.parsing.sympy_parser.parse_expr('expr2')
print(type(expr2b), '->', expr2b)
expr2c = sp.N(sp.parsing.sympy_parser.parse_expr('expr2'))
print(type(expr2c), '->', expr2c)
#print(sp.N(sp.parsing.sympy_parser.parse_expr('expr2')))
expr2d = sp.sympify('expr2')
print(type(expr2d), '->', expr2d)

与输出

<class 'sympy.core.mul.Mul'> -> 1.01*a**1.01*b**0.99
<class 'sympy.core.symbol.Symbol'> -> expr2
<class 'sympy.core.symbol.Symbol'> -> expr2
<class 'sympy.core.symbol.Symbol'> -> expr2

我需要一些东西,接受字符串'expr2'并返回表达式1.01 * a**1.01 * b**0.99


我的尝试都没有达到目的。没有帮助的问题或链接(至少对我来说):

  1. 从字符串到症状表达式
  2. https://docs.sympy.org/latest/tutorials/intro-tutorial/basic_operations.html
  3. https://docs.sympy.org/latest/modules/parsing.html
  4. https://docs.sympy.org/latest/modules/core.html sympy.core.sympify.sympify
  5. https://docs.sympy.org/latest/tutorials/intro-tutorial/manipulation.html

如果,在解析时,您想要使用已映射到变量的表达式,则必须传递python用于跟踪这些映射的字典,即locals()

>>> from sympy.abc import x
>>> from sympy import sympify, parse_expr
>>> y = x + 2
>>> sympify('y')
y
>>> sympify('y', locals=locals())
x + 2
>>> parse_expr('y', local_dict=locals())
x + 2

根据Sympy Google小组的Oscar Benjamin的建议,eval完成了这项工作

def verify_ratio(vstr1, vstr2):
"""Compare the result of two different computations of the same quantity"""
print(vstr1 + ' / ' + vstr2, '=', eval(vstr1 + ' / ' + vstr2))
return

>>> import sys
>>> import sympy as sp
>>> a, b = sp.symbols('a,b', real=True, positive=True)
>>> a is eval('a')
True

在我的情况下,我在vstr1vstr2中使用的所有表达式和符号都是全局的。如果在其他函数中嵌套,我可能需要向verify_ratio传递更多的参数,就像smichr的解决方案一样。

相关内容

  • 没有找到相关文章

最新更新