2013-12-19 7 views
7

一般的な問題numpyの:複数の外積

私は形状(nrow,ncols,3)ndarrayvを持っていると仮定します。私は、形outer_arrayの形状(nrow,ncols,3,3)を、それぞれのインデックス(nrow,ncol)で形状(3)のベクトルのすべての外積を含むように計算したいと思います。もちろん、これはnumpy.einsumが存在する種類の問題です。 さて、私が試したことはある:

outer_array = numpy.einsum("xyi,xyj->xyij",v,v.conjugate()) 

今、私はこれが動作することをわからない:outer_arrayは対応していない予想される形状、外積の行列の要素を持っているという事実にもかかわらず私が期待しているものまで

私は、これはeinsum式のラベルの選択によるものだと思う:私は出力式でそれらを再利用していますから、結果をインデックスが繰り返されているため、製品をxyにわたって加算されることになっているが、合計の何とか放送されます。一方

、私が書く場合:

outer_array = numpy.einsum("xyi,uvj->...ij",v,v.conjugate()) 

numpyのは、対角線(u,v) = (x,y)が含む形状(ncols,nrow,ncols,nrow,3,3)の配列、その結果、各対(x,y)(u,v)ため外積のすべての可能な組み合わせを計算します所望の出力。

私が頼ることなく、各インデックスx,yで私はそれ自体とベクターvの外積を得る配列を得るためにeinsum表記の最初の2つのインデックスの選択方法精密質問

2番目の式に?

編集 どうやら、このフォームはあまりにも動作するようです:

outer_array = numpy.einsum("...i,...j->...ij",v,v.conjugate()) 

私はnumpyの放送がどのように便利なだけ鑑賞することができます!

+4

「期待していたものと一致しません」という出力例を掲載できますか?あなたの最初のアプローチは正しいことのように思えます。 – Jaime

+0

あなたは本当に正しいです。予期せぬ結果の問題は別の問題によるものです。 'x'と' y'のインデックスが合計されるという条件で繰り返され、再び出力に現れるので、私は自分のコードがどのように動作するのか、まだ疑問に思います。誰かがそれを説明できますか? – Bafe

+0

関連性があります:http://stackoverflow.com/q/17138393/1461210 –

答えて

4

の鍵は、xyが出力文字列で繰り返されていることです。これはnumpyの放送の例(すなわち、それらを寸法を追加して拡大)

ある

In [20]: x[:,:,None]*x[:,None,:] # shape (3,2,2) 
Out[20]: 
array([[[ 0, 0], 
     [ 0, 1]], 

     [[ 4, 6], 
     [ 6, 9]], 

     [[16, 20], 
     [20, 25]]]) 

:このxに外積のための今すぐ

x = np.arange(6).reshape(3,2) 
np.einsum.einsum('ij->j',x) 
# array([6, 9]) # sums on the 1st dimension of `x` 

のは、単純な配列を使用してみましょう

"...i,...j->...ij"では、...は、既存の匿名のディメンションのプレースホルダとして機能しています。einsum

同等です:

np.einsum('ij,ik->ijk',x,x) 

(私は本当に最後の2次元で対称されていない計算を行う必要があります)。

私はeinsumの純粋なPythonの仕事に似ています。フォーカスは、引数文字列の解析と、iterオブジェクトの入力の作成方法です。これはgithubで利用可能です:https://github.com/hpaulj/numpy-einsum/blob/master/einsum_py.pyあなたと一緒に遊ぶことができます。中間ステップを示すフラグはdebugです。出力デバッグと私einsumで

In [23]: einsum_py.myeinsum('ij,ik->ijk',x,x,debug=True) 
# ... some parsing information 
[('ij', [105, 106], 'NONE'), ('ik', [105, 107], 'NONE')] 
('ijk', [105, 106, 107], 'NONE') 
iter labels: [105, 106, 107],'ijk' 

op_axes [[0, 1, -1], [0, -1, 1], [0, 1, 2]] 

op_axesiterの作成に使用されるキー引数、入力及び出力アレイの軸に対して反復オブジェクトです。すべての配列の第1軸を反復処理します。 2番目の軸は1番目の演算と出力では1、2番目の演算ではnewaxis(-1)です。 ellipsis

In [24]: einsum_py.myeinsum('...j,...k->...jk',x,x,debug=True) 
... 
iter labels: [0, 106, 107],'0jk' 
op_axes [[0, 1, -1], [0, -1, 1], [0, 1, 2]] 

これは同じop_axesを生成し、したがって同じ計算。

+0

ありがとうございます。別の非常に簡単な質問:出力文字列で 'XY'を繰り返す正確な効果は何ですか?これらの指標に対する総和を抑えていますか? – Bafe

+0

http://docs.scipy.org/doc/numpy/reference/arrays.nditer.html#reduction-iteration - '書き込み可能なオペランドの要素数が完全な反復空間より少ない場合、そのオペランドは減算されます。言い換えれば、それは合計をトリガする欠落した 'xy'です。 – hpaulj

関連する問題