Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/opengl/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python/numpy:对嵌套循环进行矢量化_Python_For Loop_Numpy_Vectorization_Nested Loops - Fatal编程技术网

python/numpy:对嵌套循环进行矢量化

python/numpy:对嵌套循环进行矢量化,python,for-loop,numpy,vectorization,nested-loops,Python,For Loop,Numpy,Vectorization,Nested Loops,在过去的几天里,我一直试图摆脱对FORTRAN的敏感,接受python的矢量化,以尽可能多地消除循环并优化代码 这个网站上的许多帖子在实现这一点上非常有用,但我遇到了一个我不知道如何解决的问题 下面是代码的for-loop版本,我承认它使用了一些不必要的数组分配,但这只是为了说明问题: mu = np.zeros( nbk ) mubins = np.linspace( -1, 1, nbk ) mu[:-1] = ( mubins[:-1] + mubins[1:] ) /

在过去的几天里,我一直试图摆脱对FORTRAN的敏感,接受python的矢量化,以尽可能多地消除循环并优化代码

这个网站上的许多帖子在实现这一点上非常有用,但我遇到了一个我不知道如何解决的问题

下面是代码的for-loop版本,我承认它使用了一些不必要的数组分配,但这只是为了说明问题:

mu       = np.zeros( nbk )
mubins   = np.linspace( -1, 1, nbk )
mu[:-1]  = ( mubins[:-1] + mubins[1:] ) / 2.

kbins    = 10**( np.linspace( kmin, kmax, nb ) )
k1       = np.zeros( nbk )
k1[:-1]  = ( kbins[:-1] + kbins[1:] ) / 2.0

nb       = 100
for i in range(         nb - 1 ):
    for j in range(     nb - 1 ):
        Bl = np.zeros( Nmodes )                 # ( will be important later ) initialising array here 
        for k in range( nb - 1 ):

            k33[i,j,k] = np.sqrt(  k1[i] * k1[i] + k1[j] * k1[j] - 2 * k1[i] * k1[j] * mu[k] )
            P11[i,j,k] = pkspline( k1[i] )      # just using intrep1d from earlier in the code - not important
            P22[i,j,k] = pkspline( k1[j] )
            P33[i,j,k] = pkspline( k33[i,j,k] )

            f212[i,j,k],s212[i,j,k] = S2F2_SLOW(k1[i],k1[j],k33[i,j,k]) # just calling some function - not important
            f213[i,j,k],s213[i,j,k] = S2F2_SLOW(k1[i],k33[i,j,k],k1[j])
            f223[i,j,k],s223[i,j,k] = S2F2_SLOW(k1[j],k33[i,j,k],k1[i])

             # computing B11 to be used in following ‘p’ loop
            B11=b1*b1*b1*P11[i,j,k]*P22[i,j,k]*2.*f212[i,j,k] + b1**2*b2*P11[i,j,k]*P22[i,j,k] + b1**2*bs2*P11[i,j,k]*P22[i,j,k]*s212[i,j,k] + b1*b1*b1*P11[i,j,k]*P33[i,j,k]*2.*f213[i,j,k] + b1**2*b2*P11[i,j,k]*P33[i,j,k] + b1**2*bs2*P11[i,j,k]*P33[i,j,k]*s213[i,j,k] + b1*b1*b1*P22[i,j,k]*P33[i,j,k]*2.*f223[i,j,k] + b1**2*b2*P22[i,j,k]*P33[i,j,k] + b1**2*bs2*P22[i,j,k]*P33[i,j,k]*s223[i,j,k]

            # new loop ( this is where my issue is ) v-v-v-v-v-v-v-v-v-v-v-v-v-v-v
            for p in range( Nmodes ):
                Bl[p] = Bl[p] + 2. * pi * LegMu[k,p] * dmu * B11
这就是代码片段。将其矢量化时,删除 外部“i”和“j”表示循环,内部“k”和“p”表示循环

下面是我的尝试:

kbins = 10**(np.linspace(kmin,kmax,nb))
kk  = np.zeros(nbk)
kk[:-1]  = (kbins[:-1]+kbins[1:])/2.0

# so from above i now create 2 new arrays that will replace k1[i] and k1[j] in the previous version 
k1 = kk[np.newaxis].T #equivalent to k1[i]
k2 = kk               #equivalent to  k1[j]

#i and j loops now removed and left with k ( i may be able to get rid of the 'k' loop as well but i can't see how)
for k in range(nbk-1):
    k3[:-1,:-1,k]=   np.sqrt(np.square(k2[:-1]) + np.square(k1[:-1]) -2*k1[:-1]*k2[:-1]*mu[k])
    print k
    P1[:-1,:-1,k]=pkspline(k1[:-1])
    P2[:-1,:-1,k]=pkspline(k2[:-1])
    P3[:-1,:-1,k]=pkspline(k3[:-1,:-1,k])

    F2_12[:-1,:-1,k],S2_12[:-1,:-1,k]=S2F2(k1[:-1],k2[:-1],k3[:-1,:-1,k])
    F2_13[:-1,:-1,k],S2_13[:-1,:-1,k]=S2F2(k1[:-1],k3[:-1,:-1,k],k2[:-1])
    F2_23[:-1,:-1,k],S2_23[:-1,:-1,k]=S2F2(k2[:-1],k3[:-1,:-1,k],k1[:-1])

    #i've now put BB into a function. 
    B11[:-1,:-1,k] = BB(b1,b2,bs2,P1[:-1,:-1,k],P2[:-1,:-1,k],P3[:-1,:-1,k],S2_12[:-1,:-1,k],S2_13[:-1,:-1,k],S2_23[:-1,:-1,k],F2_12[:-1,:-1,k],F2_13[:-1,:-1,k],F2_23[:-1,:-1,k])
我将B数组从k循环中取出,然后写下:

B11 = BB( b1,b2,bs2,P1,P2,P3,S2_12,S2_13,S2_23,F2_12,F2_13,F2_23 )
然而,我似乎无法理解的是,如何从这一点出发,合并p循环,因为它嵌套在k循环中:

关键的是,如果你看第一个版本,我必须在调用k循环之前将Bl数组设置为零。在这之后会发生一些事情,使用Bl,但这就是我现在被困的地方

任何帮助都将不胜感激

好的,根据要求,我将简化以上内容,以便更好地说明问题的机理。您可以忽略我指定的数组值-这只是一个示例:

所以从for循环版本开始

kbins  = linspace( -1, 1, 100 ) )
mubins = linspace( -5, 5, 100 ) )

nb     = 100

BLB    = np.zeros( 10 )           # <--------------------------------- see q loop

for i in range(         nb - 1 ):
    k1 = ( kbins[i] + kbins[i+1] ) / 2.0

    for j in range(     nb - 1 ): 
        k2 = ( kbins[j] + kbins[j+1] ) / 2.0

        BL = np.zeros( 10 )      # <---------------------------------- see 'p' loop

        for k in range( nb - 1 ):
            mu = ( mubins[k] + mubins[k+1] ) / 2.
            k3 =  np.sqrt( k1 + k2 - 2 * mu )

            x = some_function(k1,k2,k3)
            y = some_function(k1,k3,k2)
            z = some_function(k2,k3,k1)

            B = x + y + z

            for p in range( 10 ):
                BL[p] = BL[p] + 2. * B

            for q in range( 10 ):
                BLB[q] = BLB[q] + BL[q]
但是我如何在各自的p和q循环中计算BL和BLB呢

我希望这更有意义。

看起来有些函数接受3个标量并返回一个标量。B也是标量。所以

        B = x + y + z

        for p in range( 10 ):
            BL[p] = BL[p] + 2. * B

        for q in range( 10 ):
            BLB[q] = BLB[q] + BL[q]
可简化为:

BL += 2*B
BLB += BL
我看不到在p和q上迭代的点。如所述,BL的所有10个值与BLB的10个值相同

当我尝试使用一个简单的some_函数(如k1+k2+k3)运行脚本时,我在k3=np.sqrt k1+k2-2*mu处得到了一个间歇性错误,可能是因为k1+k2-2*mu可能变为负值。但忽略这一点,我认为您的脚本简化为:

nb     = 11
kbins  = np.linspace( -1, 1, nb )
mubins = np.linspace( -5, 5, nb )

kx = (kbins[:-1]+kbins[1:])/2.0
kmx = (mubins[:-1]+mubins[1:])/2.0

for k1 in kx:
    BLB = 0
    for k2 in kx:
        BL = 0
        for mu in kmx:
            B = k1+k2-2*mu
            BL += 2*B
        BLB += BL
    print BLB
在这里,我处理了BL和BLB总和的嵌套,所以它们有一定的意义

如果可以将内部标量计算推广到3D数组,我们就可以将整个过程矢量化

k1 = kx[:, None, None]
k2 = kx[None, :, None]
mu = kmx[None, None,:]
B = 2*(k1 + k2 - 2*mu)
# (nb-1, nb-1, nb-1)
BL = np.sum(B, axis=2)
BLB = np.sum(BL, axis=1)
print BLB
回顾第一个脚本,p循环有点复杂

for p in range( Nmodes ):
            Bl[p] += X[k,p] * B
假设X是某种2d系数数组,则其工作原理如下:

Bl += X[k,:] * B

你能写一个简单的例子吗?这是相当复杂的——但是如果你写一个简单的例子,抓住你试图解决的问题的所有基本特征,它会更容易帮助你。你甚至可能会发现你可以自己解决这个问题。现在就看吧,谢谢。好的,在原始帖子的底部添加了一个精简版。我希望这一点现在更清楚一些。感谢for-loop版本,Bl[p]应该是Bl[p]吗?@russelljohnston你能澄清一下你的优先级吗?您是在寻求如何提高代码执行速度,还是理解矢量化作为一种代码设计方法?另外,请确认p&q循环的缩进级别是否正确,是否只是外部k循环内的一个串行代码块。谢谢你的回答!因此,为了澄清,我在示例中为kbins和mubin提供的值只是为了简单起见。我将在我最初的帖子底部澄清p和q实际上在做什么。
for p in range( Nmodes ):
            Bl[p] += X[k,p] * B
Bl += X[k,:] * B