2017-08-29 16 views
4

で混合可変用語を削除SymPyシンボルeiの二つの機能を検討:これは、しかしながらSymPy級数展開

z = e**3*i**3 + e**3*i**2 + e**3*i + e**3 + e**2*i**3 + e**2*i**2 + e**2*i + e**2 + e*i**3 + e*i**2 + e*i + e + i**3 + i**2 + i + 1 

を生成eiが共に小さいことを想定します

from sympy import Symbol, expand, Order 
i = Symbol('i') 
e = Symbol('e') 
f = (i**3 + i**2 + i + 1) 
g = (e**3 + e**2 + e + 1) 
z = expand(f*g) 

を3次以上の項を無視することができます。 Sympyのシリーズのツールを使用して、または単にO-記法Orderクラスはこれを扱うことができます追加:

In : z = expand(f*g + Order(i**3) + Order(e**3)) 
Out: 1 + i + i**2 + e + e*i + e*i**2 + e**2 + e**2*i + e**2*i**2 + O(i**3) + O(e**3) 

ことは素晴らしいです。しかし、私はまだ混在の言葉で残っていますe**2 * i**2。これらの用語の個々の変数は、SymPyがそれらを保持するように、所望のカットオフよりも小さい。しかし、数学的には小さい²・小さい²=小さい⁴。同様に、e・i²= small・small²=small³。

少なくとも私の目的のために、これらの混合用語を削除します。混合してOrderを追加しても、目的の結果は得られません(最初の2つの注文は無視されるようです)。

In : expand(f*g + Order(i**3) + Order(e**3) + Order((i**2)*(e**2))) 
Out: 1 + i + i**2 + i**3 + e + e*i + e*i**2 + e*i**3 + e**2 + e**2*i + e**3 + e**3*i + O(e**2*i**2, e, i) 

質問:んSymPy素早くn次の項を削除するための簡単なシステムを持っている、などの用語です(E^A)・(I^B)ここで、+ B> N ?

厄介な解決策:私はこれを解決する方法を見つけましたが、それは面倒で潜在的に一般的ではありません。

z = expand(f*g + Order((e**2)*i) + Order(e*(i**2))) 
zz = expand(z.removeO() + Order(e**3) + Order(i**3)) 

私がしたい正確に何である

zz = 1 + i + i**2 + e + e*i + e**2 + O(i**3) + O(e**3) 

を生成します。だから私の質問を指定する:任意のnに一般化することができる1つのステップでこれを行う方法はありますか?また、私のソリューションは、混合用語が失われたことを示すbig-O表記を失います。これは必要ではないがいいだろう。

答えて

1

二重制限があるため、すべてのOrderオブジェクトには、最初の引数に表示されない場合でも、両方の微小変数(eおよびi)を指定する必要があります。

この理由は、Order(expr)のみ自動的に実際exprに現れる微小として、これらのシンボルを選択し、したがって、例えば、O(e)のみ制限E→0であるということです。 今、さまざまな制限にOrderオブジェクトがうまく混ざらない、例えば:

O(e*i)+O(e) == O(e*i) != O(e)+O(e*i) == O(e) # True 

これは、結果が、これは避けるべきものであることを示す良い指標である添加の順序に依存混乱につながります。 これは、(加算引数として、Orderのような)無限小の記号を明示的に指定することによって避けることができる。:あなたが試みるかもしれない注文を使用しない

orders = sum(Order(e**a*i**(n-a),e,i) for a in range(n+1)) 
expand(f*g+orders) 
# 1 + i + i**2 + e + e*i + e**2 + O(e**2*i, e, i) + O(e*i**2, e, i) + O(i**3, e, i) + O(e**3, e, i) 
1

O(e*i)+O(e,e,i) == O(e,e,i)+O(e*i) == O(e,e,i) # True 

私は手動でeiのすべての組み合わせを経ないようにする方法を発見していないが、これは単純な反復処理によって行うことができますこのような単純なもの:

>>> eq = expand(f*g) # as you defined 
>>> def total_degree(e): 
...  x = Dummy() 
...  free = e.free_symbols 
...  if not free: return S.Zero 
...  for f in free: 
...   e = e.subs(f, x) 
...  return degree(e) 
>>> eq.replace(lambda x: total_degree(x) > 2, lambda x: S.Zero) 
e**2 + e*i + e + i**2 + i + 1