定义和求解无冗余方程(Python)

2024-04-29 11:25:31 发布

您现在位置:Python中文网/ 问答频道 /正文

建立物理方程的标准方法似乎是以下方法: physics equation in python 在stackoverflow post中,你可以使用你的等式,它是s = v*t,或者写多个函数,如下所示:

def s(v, t):
    return v*t

def v(s, t):
    return s/t

def t(s, v):
    return s/v

或者你在一个大的分支方程中也做同样的事情

def solve_svt_equation(v=None, t=None, s=None):
    if v is not None and t is not None:
        return v * t   # s case
    elif s is not None and t:  # t not None and not 0
        return s / t   # v case
    elif s is not None and v: # v not None and not 0
        return s / v

print(solve_svt_equation(v=10, t=2))
print(solve_svt_equation(s=2, t=7))

如果只有一个物理方程,程序员将不得不实现,这将是一个可行的方法,没有更多的担心。然而,如果您需要实现许多等式,这种方法很容易出错,并且很快就会变得混乱

对于我即将进行的编码项目,大约有50个这样的方程。我想我正处于许多程序员已经处于的一种常见情况

由于v*t - s = 0完全定义了方程,因此可能存在一种解决方案,程序员只需编写一次方程。它可以看起来像是这个虚构的想法(或其他任何东西):

Equation svt = Equation("v*t - s")
svt['s'] = 12
svt['v'] = 6
print(svt.get('t'))

所以我的问题是Python库中是否有这样的解决方案,是否有一个干净可行的标准方法,还是我必须自己想出一个解决方案


Tags: and方法nonereturnisdef物理not
1条回答
网友
1楼 · 发布于 2024-04-29 11:25:31

Python生态系统中有许多库来处理这些问题

一个是SymPy

代码可能如下所示:

import sympy

def solve_svt_equation(v=None, t=None, s=None):
    velocity, space, time = sympy.symbols("v s t")
    expr = velocity * time - space
    if v:
        expr = expr.subs(velocity, v)
    if t:
        expr = expr.subs(time, t)
    if s:
        expr = expr.subs(space, s)
    return sympy.solve(expr)

print(solve_svt_equation(v=10, t=2)) # [20]
print(solve_svt_equation(s=2, t=7)) # [2/7], sympy defaults to rational numbers
print(solve_svt_equation(s=2, t=7, v=1)) # [], no solution
print(solve_svt_equation(s=2)) # [{t: 2/v}], symbolic solution for t

一个可能更容易概括的替代方案是:

def solve_svt_equation(v=None, t=None, s=None):
    velocity, space, time = sympy.symbols("v s t")
    expr = velocity * time - space
    vals = {velocity: v, space: s, time: t}
    for symbol, val in vals.items():
        if val:
            expr = expr.subs(symbol, val)
    return sympy.solve(expr)

如果要从字符串生成表达式,可以使用sympy.parsing.sympy_parser.parse_expr生成类似于示例的内容

svt_expr = sympy.parsing.sympy_parser.parse_expr("v*t - s")
svt_expr = svt_expr.subs("s", 12)
svt_expr = svt_expr.subs("v", 6)
print(sympy.solve(svt_expr, "t")) # [2]

另一个伟大的库是z3,它是一个SMT解算器,而不是一个符号操作库,但可以轻松解决这些简单的问题。如果你有符号方程,我会建议你使用sympy,只是把它作为一种选择

import z3
v, s, t = z3.Reals("v s t")
equation = v * t == s
z3.solve([equation, s == 12, v == 6]) # Prints [v = 6, s = 12, t = 2]

相关问题 更多 >