2

Python で次のコードを最適化したいと思います。

for imode in N.arange(3*natom): #Loop on perturbation (6 for 2 atoms)
  for ikpt in N.arange(nkpt):
    for iband in N.arange(nband):    
      for iatom1 in N.arange(natom):
        for iatom2 in N.arange(natom):
          for idir1 in N.arange(0,3):
            for idir2 in N.arange(0,3):    
              fan_corrQ[imode,ikpt,iband] += EIG2D[ikpt,iband,idir1,iatom1,idir2,iatom2]*\
                  displ_red_FAN2[imode,iatom1,iatom2,idir1,idir2]
              ddw_corrQ[imode,ikpt,iband] += ddw_save[ikpt,iband,idir1,iatom1,idir2,iatom2]*\
                  displ_red_DDW2[imode,iatom1,iatom2,idir1,idir2]

ご覧のとおり、マルチスペース python 配列のいくつかのインデックスを合計したいと思います。次のようなものが欲しいです:

for imode in N.arange(3*natom): #Loop on perturbation (6 for 2 atoms)
  for ikpt in N.arange(nkpt):
    for iband in N.arange(nband):
      fan_corrQ[imode,ikpt,iband] = N.dot(EIG2D[ikpt,iband,:,:,:,:],displ_red_FAN2.T[imode,:,:,:,:])
      ddw_corrQ[imode,ikpt,iband] = N.dot(ddw_save[ikpt,iband,:,:,:,:],displ_red_DDW2.T[imode,:,:,:,:])

もちろん、同じインデックスを乗算しないという問題があるため、再定義しました。また、複素数を扱っていることも指摘する必要があります。

displ_red_DDW2 = N.zeros((3*natom,3,natom,3,natom),dtype=complex)

また、ipython で小さなダミー プログラムを試してテストしました。

import numpy as N
atom =2
displ_red_FAN2 = N.zeros((3*natom,3,natom,3,natom),dtype=complex)
EIG2D = N.zeros((216,12,3,2,3,2))

だから私は displ_red_FAN2.shape = (6, 3, 2, 3, 2) と EIG2D.shape = (216, 12, 3, 2, 3, 2) を持っています

したがって、次のようなことをすると:

N.dot(EIG2D[1,1,:,:,:,:],displ_red_FAN2[1,:,:,:,:].T).shape

(3,2,3,2) を与えるべきですが、代わりに (3, 2, 3, 2, 3, 3) を与えます ??? 次に、乗算が完了したら、次元を減らすために何らかの合計を行う必要があると思います。

どんな助けでも素晴らしいでしょう!

乾杯!

サミュエル

4

2 に答える 2

3

使用できますnp.tensordot()

fan_corrQ = np.tensordot(displ_red_FAN2, EIG2D, axes = ([3,1,4,2],[2,3,4,5]))
ddw_corrQ = np.tensordot(displ_red_DDW2, ddw_save, axes = ([3,1,4,2],[2,3,4,5]))

これにより、現在のアプローチと同じ結果が得られ、ほぼ9 times高速になります。

あなたの他の質問について。np.dot()for aは、最初の配列の最後の軸と 2 番目の配列の最後から 2 番目の軸を合計しND-arrayます。

于 2013-06-29T11:51:34.643 に答える