我正试图通过访问fortran中的边界元素来检查我的数组是否正在返回废话。我想检查这些值是否小于1,如果是,则将它们更改为1。
这是导致问题的代码:
lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/)
LastNeighLabel包含分别为x,y,z方向的最后一个邻居的簇标签(介于1和n之间,其中n是找到的唯一单独簇的总数)。
当jj
或kk
或ll
为1时,他们会尝试访问数组中的第0个元素,而FORTRAN
从数组中的1开始计数,它会尝试摧毁宇宙我目前正处于一个混乱的大约8个if / elseif语句试图为每个可能性编码。但我希望有一种方法可以对每个元素进行操作。所以基本上我想说where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc
取决于导致问题的因素。
但我想不出办法做到这一点,因为哪里只会操纵传递给它的变量,而不是同一个索引的不同数组。或者我错了吗?
如果没有意义的话,很乐意编辑。
答案 0 :(得分:4)
Fortran从一开始访问数组并不是强制性的。允许任何起始值。如果您拥有零索引数组更方便,请将数组声明为:
real, dimension (0:N-1, 0:M-1) :: array
或者
real, dimension (0:N, 0:M) :: array
并且0指数是额外的以捕捉特殊情况。
这可能是您问题的另一种解决方案,因为零索引值是合法的。
答案 1 :(得分:3)
另一种可能的方法是创建一个扩展的集群标签数组(索引边界从0开始),它等于集群标签数组,外部有一层零。然后,您可以让循环在jj,kk和ll的所有值上安全运行。如果这是一个可行的解决方案,它取决于数组的大小。
integer :: extended_cluster_label(0:size(cluster_label,1), & 0:size(cluster_label,2), & 0:size(cluster_label,3) & ) extended_cluster_label(0,:,:) = 0 extended_cluster_label(:,0,:) = 0 extended_cluster_label(:,:,0) = 0 extended_cluster_label(1:, 1:, 1:) = cluster_label
答案 2 :(得分:2)
也许你可以使用一个函数?
real function f(A,i,j,k)
real :: A(:,:,:)
integer :: i,j,k
if (i==0.or.j==0.or.k==0) then
f=0
else
f=A(i,j,k)
endif
end function f
然后使用f(clusterLabel,jj-1,kk,ll)等。