将字符串转换为数学函数:"名称sint未定义"

时间:2018-04-23 18:03:05

标签: python string function sympy symbols

我有一个字符串格式的函数f(t,u,v);例如't^2 * sint + u*(20 + t) + v*t'

我该如何解决这个功能?

我试着这样做:

t = Symbol('t')
u = mu
v = mv
sol = eval(f)

但我收到错误name 'sint' is not defined

2 个答案:

答案 0 :(得分:1)

使用eval不是最好的方法。 SymPy parser具有允许使用t^2(称为convert_xor)和sin t(称为implicit_application)等内容解析字符串的选项。这是一个例子:

from sympy.parsing.sympy_parser import parse_expr, standard_transformations, implicit_application, convert_xor
transformations = standard_transformations + (implicit_application, convert_xor)
f = parse_expr('t^2 * sin t + u*(20 + t) + v*t', transformations=transformations)

现在ft**2*sin(t) + t*v + u*(t + 20),您可以正常使用它,例如

solve(f.subs({Symbol('u'): 4}), Symbol('v'))    # returns [-t*sin(t) - 4 - 80/t]

您可能希望介绍u, v, t = symbols('u v t')以便更轻松地访问这些符号。

不幸的是sint不会被识别为sin(t);缺乏空间是致命的。这必须经过预处理,可能使用正则表达式。例如,

import re
s = re.sub(r'\bsin', 'sin ', 't^2 * sint + u*(20 + t) + v*t')

在每次“罪恶”之后留下一个空间(额外的空间不会受到伤害)。

答案 1 :(得分:0)

这相当丑陋,但您可以在评估表达式之前使用正则表达式(稍微)格式化表达式。您可能不得不在下面修改以下代码以满足您的需求。

import re
import textwrap
import math

functionBaseCode = textwrap.dedent("""
    def f({variables}):
        return {mathExpr}
    """)

def generateFunctionFromExpression(expression, variables):

    expression = expression.replace("^", "**")
    for fname in ["sin", "cos", "exp", "log", "sqrt"]:
         pattern = r"{fname} ?([a-zA-Z0-9]*)".format(fname = fname)
         replacement = r"math.{fname}(\1)".format(fname = fname)
         expression = re.sub(pattern, replacement, expression)

    variables = ", ".join(variables)
    mathExpr = expression
    funCode = functionBaseCode.format(
        variables = variables,
        mathExpr = mathExpr)

    # print(funCode)

    definitions = {}
    eval(compile(funCode, "<string>", "exec"), globals(), definitions)
    f = definitions["f"]

    return f

f = generateFunctionFromExpression("t^2 * sint + u*(20 + t) + v*t", "t u v".split())
g = generateFunctionFromExpression("x^2 + y^2", ["x", "y"])
# h = generateFunctionFromExpression("sqrt(x^2 + y^2)")
# l = generateFunctionFromExpression("log(sqrt(x)) - log(x) / 2", ["x"])
# h and l would fail because of the parenthesis after sqrt and log.

print(f(1, 1, 1)) # 22.8414
print(g(2, 3)) # 13