Pythonic方法管理任意数量的变量,用于求解方程。

2024-09-25 00:33:51 发布

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

如果没有直接的例子,这有点难以解释。让我们以非常简单的ideal-gas law为例。对于正常情况下的理想气体,以下方程成立:

PV = RT

这意味着,如果我们知道4个变量中的3个(压力、体积、比气体常数和温度),我们就可以求解另一个变量。在

我怎么把这个放在物体里面?我想要一个对象,在这里我可以插入3个变量,然后计算第4个变量。我想知道这是否可以通过属性来实现?在

我目前的最佳猜测是插入如下内容:

^{pr2}$

尽管这非常麻烦,而且容易出错(我必须添加检查,以确保其中一个参数被设置为“None”)。在

有没有更好、更干净的方法?在

我看到这个“问题”经常发生,以各种各样的方式,尤其是一旦变量的数量增加(将密度、雷诺数、粘度加到混合物中),不同if语句的数量就会迅速增长。(即如果我有8个变量,任何5个变量使系统唯一,我需要8个nCr 5=56个if语句)。在


Tags: 数量if情况体积语句例子方程gas
3条回答

一种解决方案是使用字典存储变量名及其值。这允许您在任何时候轻松添加其他变量。此外,您可以通过计算字典中“None”项的数量来检查是否只有一个变量具有值“None”。在

使用sympy,和kwargs检查用户提供的信息的基本解决方案:

from sympy.solvers import solve
from sympy import Symbol
def solve_gas_properties(**kwargs):
    properties = []
    missing = None
    for letter in 'PVRT':
        if letter in kwargs:
            properties.append(kwargs[letter])
        elif missing is not None:
            raise ValueError("Expected 3 out of 4 arguments.")
        else:
            missing = Symbol(letter)
            properties.append(missing)
    if missing is None:
        raise ValueError("Expected 3 out of 4 arguments.")
    P, V, R, T  = properties
    return solve(P * V - R * T, missing)

print solve_gas_properties(P=3, V=2, R=1) # returns [6], the solution for T

如果您想在系统中存储和操作不同的值,则可以将其转换为类方法,利用类属性而不是关键字参数。在

上述内容也可改写为:

^{pr2}$

使用^{},可以为每个方程创建一个类。用ω, π = sp.symbols('ω π')等创建方程的符号,方程本身,然后使用函数f()来完成剩下的工作:

import sympy as sp    

# Create all symbols.
P, V, n, R, T = sp.symbols('P V n R T')
# Create all equations
IDEAL_GAS_EQUATION = P*V - n*R*T   

def f(x, values_dct, eq_lst):
    """
    Solves equations in eq_lst for x, substitutes values from values_dct, 
    and returns value of x.

    :param x: Sympy symbol
    :param values_dct: Dict with sympy symbols as keys, and numbers as values.
    """

    lst = []
    lst += eq_lst

    for i, j in values_dct.items():
        lst.append(sp.Eq(i, j))

    try:
        return sp.solve(lst)[0][x]
    except IndexError:
        print('This equation has no solutions.')

尝试一下。。。公司名称:

^{pr2}$

如果您没有通过values_dct提供足够的参数,您将得到一个类似3*T/2的结果,检查它的type(),得到<class 'sympy.core.mul.Mul'>。在

如果您确实提供了结果为6而其类型为<class 'sympy.core.numbers.Integer'>的所有参数,那么您可以引发异常或任何需要的参数。您还可以使用int()将其转换为int(如果使用3*T/2而不是6,则会引发一个错误,因此您也可以这样测试它)。在

或者,您可以简单地检查values_dct中的None值是否大于1。在


要组合多个方程,例如PV=nRTP=2m,可以像前面的符号一样创建额外的符号m,并将{}分配给新的方程名MY_EQ_2,然后将其插入函数的eq_lst

m = sp.symbols('m')
MY_EQ_2 = P - 2 * m

vals = {n: 3, R: 1, T:4}

r = f(V, values_dct=vals, eq_lst=[IDEAL_GAS_EQUATION, MY_EQ_2])
print(r)   # Prints 6/m

相关问题 更多 >