2016-06-27 15 views
2

dot名前を付けることを起こる未定義の機能を取り、そしてそれlambdifyの一部行いますドットとSymPyのlambdify()

import numpy 
import sympy 


class dot(sympy.Function): 
    pass 

x = sympy.Symbol('x') 

a = sympy.Matrix([1, 0, 0]) 
f = sympy.lambdify(x, dot(a.T, x)) 

x = numpy.array([3, 2, 1]) 
print(f(x)) 

サプライズ:これは実際に動作します!

明らかに、文字列"dot"が何らかの形で抽出され、ドットプロダクトの実装に置き換えられました。誰が知っていますか?

上記の結果は[3]です。しかし、私はスカラーを得るのが好きです3。 (どのように)それを達成するためにf()を変更できますか?

答えて

2

私はしかし、それは言うlambdifyのドキュメントを引用sympyユーザーではないよ:ユーザーによって異なって指定されていない場合は、SymPy関数は(どちらかpython-mathnumpyによって可能な限り を交換している

利用可能な場合)または mpmathの機能 - この順番になります。この動作を変更するには、 "modules"引数を使用できます。それは受け入れる:

  • 文字列「数学」、「mpmath」、「numpyの」、「numexpr」、「sympy」
  • 任意のモジュール(例えば数学)にsympy関数の名前をマップ
  • 辞書任意の関数
  • 上記の引数の組み合わせを含むリストで、最初に表示されるエントリの優先度が高くなります。

だから、あなたがpython-mathがインストールされている場合ではない場合、それは、それを使用しますようですが、あなたはnumpyはそれがnumpyのバージョンを使用しますインストールされている、そうでない場合はmpmatし、この動作を変更する方法について説明します。

dotを必要に応じて返す関数にマップする辞書であるmodulesの値を入力するだけです。


私が何を意味するかの例:あなたはあなたが欲しいものを達成することができmodules引数を操作することで見ることができるように

>>> import numpy as np 
>>> import sympy 
>>> class dot(sympy.Function): pass 
... 
>>> x = sympy.Symbol('x') 
>>> a = sympy.Matrix([1,0,0]) 
>>> f = sympy.lambdify(x, dot(a.T, x), modules=[{'dot': lambda x, y: np.dot(x, y)[0]}, 'numpy']) 
>>> y = np.array([3,2,1]) 
>>> print(f(y)) 
3 
>>> print(type(f(y))) 
<class 'numpy.int64'> 

。ここでの私の実装では絶対にナイーブですが、好きなことを一般化することができます

>>> def my_dot(x, y): 
...  res = np.dot(x, y) 
...  if res.ndim == 1 and res.size == 1: 
...   return res[0] 
...  return res 

この機能のチェックは、通常のdotの結果はスカラーであり、従って、プレーンスカラーを返し、そうでない場合np.dotと同じ結果を返すかどうか。

+0

コメントありがとうございます! 'sympy.Matrix([1,2,3])'が2次元のベクトル 'numpy.array([1,2])に変換されるということは、' dot() '自体が私が信じる犯人ではありません。 、3]]) '。これにより、numpyの 'dot'が配列を返します。 –

+1

@NicoSchlömer私はあなたが 'modules'引数を使って望むものを達成する方法の例を追加しました。ご覧のとおり、動作します。私はあなたの小さなカスタム機能を提供せずにこれを達成する他の方法があるかどうか分かりません。 – Bakuriu

+0

一般に、numpy関数に関数をラムダイズすると、numpy関数が出力するものなので、出力は配列になるはずです。 – asmeurer