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

标签 python equation-solving

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

PV = RT

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

我如何将其放入对象中?我想要一个对象,我可以在其中插入 3 个变量,然后计算第 4 个。不知是否可以通过属性来实现?

我目前最好的猜测是像这样插入它:

class gasProperties(object):
    __init__(self, P=None, V=None, R=None, T=None)
        self.setFlowParams(P, V, R, T)
    def setFlowParams(self, P=None, V=None, R=None, T=None)
        if P is None:
            self._P = R*T/V
            self._V = V
            self._R = R
            self._T = T
        elif V is None:
            self._V = R*T/P
            self._P = P
            self._R = R
            self._T = T
        #etc

虽然这很麻烦,而且容易出错(我必须添加检查以查看是否恰好有一个参数设置为“无”)。

有没有更好、更简洁的方法?

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

最佳答案

使用 sympy ,您可以为每个方程式创建一个类。使用 ω, π = 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.')

试试这个……:

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

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

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

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

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


合并多个方程,例如PV=nRTP=2m , 你可以创建额外的符号 m像前面的符号一样分配 2m到新方程名称 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

关于管理任意数量变量的 Pythonic 方式,用于方程求解。,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29253418/

相关文章:

python - 在多变量情况下使用 SymPy 求解时限制解集的域

python - 计算 Pandas 中连续两行之间的时间差

python - 使用 bigquery tables GET api 获取表的最后修改日期

python - 创建对象的继承问题

python - 在 Apache/mod_wsgi 上运行 Django 时出错

java - 如何以编程方式求解多元方程组?

r - 如何解有求和的方程?

python - 为什么相同的过程在Rust中比在Python中花费更长的时间?

python - fsolve 总是返回猜测/估计

python - 为什么scipy.optimize.root 会四次调用初始值的回调函数?