检查方程对于一组特定的变量是否是线性的
Check if an equation is linear for a specific set of variables
我有一个自动生成方程式的纸条。
方程式是使用 sympy 符号构建的。
我想知道这些是否是一种检查方程是否在某些变量方面是线性的方法。
例如
a, b, c, d = sympy.symbols('a, b, c, d')
eq1 = c*b*a + b*a + a + c*d
检查以下内容:eq1
根据 a
、d
是线性的吗?
True
如果所有二阶导数都相同为零(包括混合导数),则函数在给定的一组变量中是(联合)线性的。可以按如下方式检查:
def is_linear(expr, vars):
for x in vars:
for y in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, y), 0):
return False
except TypeError:
return False
return True
在循环中,取每个导数并检查是否等于零。如果 sympy 无法确定它是否为零(引发 TypeError),那么它不完全为零。
输出:
>>> is_linear(eq1, [a,d])
True
>>> is_linear(eq1, [a,c])
False
要检查单独的线性(例如,分别在 a 中和单独在 b 中),删除混合偏导数:
def is_separately_linear(expr, vars):
for x in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, x), 0):
return False
except TypeError:
return False
return True
输出:
>>> is_separately_linear(eq1, [a,d])
True
>>> is_separately_linear(eq1, [a,c])
True
扩展404的答案,如果fxy=0,则fyx=0。因此,对于混合导数解决方案,计算时间可以减少一半。
from itertools import combinations_with_replacement
def is_linear(expr, variables):
combs = combinations_with_replacement(variables, 2)
try:
return all(sympy.Eq(sympy.diff(expr, *t), 0) for t in combs)
except TypeError:
return False
一种更简单的方法是检查每个变量中作为多项式的表达式的次数。
In [17]: eq1 = c*b*a + b*a + a + c*d
In [18]: degree(eq1, a)
Out[18]: 1
In [19]: degree(eq1, d)
Out[19]: 1
如果多项式次数 <= 1,则表达式是线性的。
如果您知道表达式是变量中的多项式,您也可以只检查包含该变量的幂。
In [21]: [i for i in eq1.atoms(Pow) if i.base == a]
Out[21]: []
In [22]: eq2 = b*a**2 + d + c
In [23]: [i for i in eq2.atoms(Pow) if i.base == a]
Out[23]:
⎡ 2⎤
⎣a ⎦
我有一个自动生成方程式的纸条。
方程式是使用 sympy 符号构建的。
我想知道这些是否是一种检查方程是否在某些变量方面是线性的方法。
例如
a, b, c, d = sympy.symbols('a, b, c, d')
eq1 = c*b*a + b*a + a + c*d
检查以下内容:eq1
根据 a
、d
是线性的吗?
True
如果所有二阶导数都相同为零(包括混合导数),则函数在给定的一组变量中是(联合)线性的。可以按如下方式检查:
def is_linear(expr, vars):
for x in vars:
for y in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, y), 0):
return False
except TypeError:
return False
return True
在循环中,取每个导数并检查是否等于零。如果 sympy 无法确定它是否为零(引发 TypeError),那么它不完全为零。
输出:
>>> is_linear(eq1, [a,d])
True
>>> is_linear(eq1, [a,c])
False
要检查单独的线性(例如,分别在 a 中和单独在 b 中),删除混合偏导数:
def is_separately_linear(expr, vars):
for x in vars:
try:
if not sympy.Eq(sympy.diff(expr, x, x), 0):
return False
except TypeError:
return False
return True
输出:
>>> is_separately_linear(eq1, [a,d])
True
>>> is_separately_linear(eq1, [a,c])
True
扩展404的答案,如果fxy=0,则fyx=0。因此,对于混合导数解决方案,计算时间可以减少一半。
from itertools import combinations_with_replacement
def is_linear(expr, variables):
combs = combinations_with_replacement(variables, 2)
try:
return all(sympy.Eq(sympy.diff(expr, *t), 0) for t in combs)
except TypeError:
return False
一种更简单的方法是检查每个变量中作为多项式的表达式的次数。
In [17]: eq1 = c*b*a + b*a + a + c*d
In [18]: degree(eq1, a)
Out[18]: 1
In [19]: degree(eq1, d)
Out[19]: 1
如果多项式次数 <= 1,则表达式是线性的。
如果您知道表达式是变量中的多项式,您也可以只检查包含该变量的幂。
In [21]: [i for i in eq1.atoms(Pow) if i.base == a]
Out[21]: []
In [22]: eq2 = b*a**2 + d + c
In [23]: [i for i in eq2.atoms(Pow) if i.base == a]
Out[23]:
⎡ 2⎤
⎣a ⎦