2016-03-29 10 views
6

私は方程式を自動的に生成するスクリプトを持っています。特定の変数の組について方程式が線形かどうかを確認します

方程式は、シンピ記号を使用して構成されます。

これは、方程式が特定の変数の点で線形かどうかを確認する方法であるかどうかを知りたいと思います。

例えば、次のため

a, b, c, d = sympy.symbols('a, b, c, d') 

eq1 = c*b*a + b*a + a + c*d 

チェック:リニアadの面でですか?

True 
+0

表現はどのくらい複雑になりますか? –

答えて

3

すべての二次導関数が全くゼロ(混在したものを含む)である場合、関数は与えられた変数のセットで(線形に)線形です。これは、次のようにチェックすることができます。

ループ内では、すべての派生が取られ、ゼロと等しいかどうかがチェックされます。 sympyが0であるかどうかを判断できない場合(TypeErrorを発生させる)、それは全く同じではありません。

出力:

>>> is_linear(eq1, [a,d]) 
True 
>>> is_linear(eq1, [a,c]) 
False 

ドロップ、(例えば、別々に及び別々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 
2

答えf rom404、f xy = 0の場合、f yx = 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 
3

もっと簡単な方法は、各変数の多項式として式の次数を調べることです。

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 ⎦ 
関連する問題