通过正确定义索引列表来提高代码效率

问题描述 投票:2回答:1

我问了这个问题avoid duplicating code by re-structuring if statement/do loop,以确定如何使我的代码更有效率。解决方案对我有很大的帮助,如下所示。

function grad(psi)
  implicit none
  integer, parameter :: nx = 24, ny = 24, nxx = nx / 2, nyy = ny / 2
  real, parameter :: pi = 4 * atan(1.0), f0 = pi ** 2 * 1.3
  complex, dimension(3,3,-nx:nx,-ny:ny) :: psi, grad

  grad(:,:,-nx+1:nx-1,-ny+1:ny-1) = psi(:,:,-nx+2:nx,-ny+1:ny-1)
  grad(:,:,0,0) = psi(:,:,1,0)
  grad(:,:,[-nxx,nxx],[-nyy,nyy,ny]) = psi(:,:,[-nxx+1,nxx+1],[-nyy,nyy,ny]) - f0 * psi(:,:,[-nxx,nxx],[-nyy,nyy,ny])

end

但是我现在需要更多地优化我的代码。

在上面的例子中,有一部分给出

grad(:,:,[-nxx,nxx],[-nyy,nyy,ny]) = psi(:,:,[-nxx+1,nxx+1],[-nyy,nyy,ny]) - ...

通过考虑列表-nxx,-nyy, -nxx, nyy,等的所有组合,有效地做我需要的。

然而,我需要的指数列表比[-nxx,nxx],[-nyy,nyy]大得多。我真的需要像[-nxx,nxx,-nxx1,nxx1,-nxx2,nxx2,-nxx3,nxx3], [-nyy,nyy,-nyy1,nyy1,-nyy2,nyy2,-nyy3,nyy3]nxx = nx/2, nxx1 = nx/4, nxx2 = nx/8, nxx3 = nx/16等。

有没有办法可以有效地做到这一点?例如,我可以只定义一个变量,例如:

integer : Listx, Listy

   Listx = [-nxx,nxx,-nxx1,nxx1,-nxx2,nxx2,-nxx3,nxx3]
   Listy = [-nyy,nyy,-nyy1,nyy1,-nyy2,nyy2,-nyy3,nyy3]

然后有类似的东西

grad(:,:,Listx,Listy) = psi(:,:,Listx+1,Listy) - ...

我确实试过这样做,但是定义Lists,List作为整数似乎给出了问题。我尝试如下:

Integer :: Listx, Listy

   Listx = [-nxx,nxx,-nxx1,nxx1,-nxx2,nxx2,-nxx3,nxx3]
   Listy = [-nyy,nyy,-nyy1,nyy1,-nyy2,nyy2,-nyy3,nyy3]

然后在编译Fortran时告诉我“不兼容的排名为0并且在...中分配”

我该如何正确定义?谢谢

fortran
1个回答
2
投票

如评论中所述,您在数组声明中缺少dimension属性:

Integer :: Listx(8), Listy(8)

这应该可以解决您的问题。任何导致rank-1数组的表达式都被允许作为向量下标索引器。

© www.soinside.com 2019 - 2024. All rights reserved.