11

3cm/µs² + 4e-4 sqmiles/km/h**2文字列 likeをそのSI 単位(この場合はm/s**2) とその大きさ (その単位の倍数)に分割したいと思います。

sympy は解析モジュール多くの物理単位と SI プレフィックスの両方を提供するため、sympyを使用するのは良い考えだと思います。しかし、これを達成するための良い方法は何ですか? 次のようなアルゴリズムを書きますが、四角い車輪を再発明することは避けたいと思います。

  • 4e-4数字と文字 ( like 構文を除く) と空白 (明示的な演算子の隣にある場合を除く)の間の遷移を乗算として扱い、トークン化します。
  • 各非数値トークンをその SI 表現で置き換えます (SI プレフィックスもチェックします)
  • 新しい式を次のように単純化しMagnitude * some SI unitsます (一貫性のない単位について意味のあるエラー メッセージを表示します。たとえば、Cannot add m**2 to s) 。

これは既存の手段で簡単に達成できますか? または、これをどのように実装するのが最善でしょうか?

4

2 に答える 2

4

単位

units解決策は、SymPyモジュールからすべてのユニットを収集し、それらを使用して、によって作成されたシンボルを置き換えることです。sympify

>>> import sympy.physics.units as u 
... subs = {} 
... for k, v in u.__dict__.items(): 
...     if isinstance(v, Expr) and v.has(u.Unit): 
...         subs[Symbol(k)] = v # Map the `Symbol` for a unit to the unit

>>> # sympify returns `Symbol`s, `subs` maps them to `Unit`s
>>> print sympify('yard*millimeter/ly').subs(subs)
127*m/1313990343414000000000

シンボルが含まれていない場合は、units不明なシンボルとして出力されます (例: barn)

>>> print sympify('barn/meter**2').subs(subs)
barn/m**2 

subsただし、いつでも辞書に追加できます。

>>> subs[Symbol('almost_meter')] = 0.9*u.meter
... sympify('almost_meter').subs(subs)
0.9*m

SI 接頭辞は、希望どおりには機能しません。乗算記号を追加する必要があります (またはkm明示的に実装されているような一般的な単位であることを願っています)。さらに、それらはインスタンスではUnitなくインスタンスであるため、それらを次Integerの場所に追加する必要があります。subs

>>> import sympy.physics.units as u
... subs = {} 
... for k, v in u.__dict__.items(): 
...     if (isinstance(v, Expr) and v.has(u.Unit)) or isinstance(v, Integer): 
...         subs[Symbol(k)] = v 

>>> print sympify('mega*m').subs(subs)
1000000*m 

Unicode の場合、前処理が必要になる場合があります。SymPy が Unicode のサポートについて約束しているとは思いません。

新しい を実装する場合はUnit、github でプル リクエストを作成することを検討してください。編集するファイルはsympy/physics/units.py.

空白と暗黙の乗算

SymPy の開発バージョンでは、適切な空白が記述されている暗黙的な乗算を想定するためのコードを見つけることができます。

>>> from sympy.parsing.sympy_parser import (parse_expr,
... standard_transformations, implicit_multiplication_application)

>>> parse_expr("10sin**2 x**2 + 3xyz + tan theta",
...            transformations=(standard_transformations + 
...                             (implicit_multiplication_application,)))
3*x*y*z + 10*sin(x**2)**2 + tan(theta) 

安全

sympifyevalこれは、Web 向けアプリに使用する場合に悪用される可能性があります。

于 2013-04-09T09:01:04.437 に答える