将字符串转换为数学函数:"name sint is not defined"



i具有字符串格式的函数 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

使用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')

在每个"罪"之后留出一个空间(额外的空间不会受到伤害(。

这很丑陋,但是您可以在评估它之前使用正则表达式(在某种程度上(格式化该表达式。您可能必须闯入以适应您的需求。

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

相关内容

最新更新