我问了这个问题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) - ...
我确实尝试过这样做,但是将Listx,Listy定义为整数似乎会带来问题。我尝试如下:
Integer :: Listx, Listy
Listx = [-nxx,nxx,-nxx1,nxx1,-nxx2,nxx2,-nxx3,nxx3]
Listy = [-nyy,nyy,-nyy1,nyy1,-nyy2,nyy2,-nyy3,nyy3]
但是在编译时,Fortran告诉我“不兼容的等级0,并且分配给...”
如何正确定义?谢谢
答案 0 :(得分:2)
如评论中所述,您在数组的声明中缺少dimension
属性:
Integer :: Listx(8), Listy(8)
这应该可以解决您的问题。任何结果为1级数组的表达式都可以用作向量下标索引器。