在数组上按元素操作

时间:2011-12-02 11:26:05

标签: arrays fortran element fortran90 indexoutofboundsexception

我正试图通过访问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是找到的唯一单独簇的总数)。

jjkkll为1时,他们会尝试访问数组中的第0个元素,而FORTRAN从数组中的1开始计数,它会尝试摧毁宇宙我目前正处于一个混乱的大约8个if / elseif语句试图为每个可能性编码。但我希望有一种方法可以对每个元素进行操作。所以基本上我想说where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc取决于导致问题的因素。

但我想不出办法做到这一点,因为哪里只会操纵传递给它的变量,而不是同一个索引的不同数组。或者我错了吗?

如果没有意义的话,很乐意编辑。

3 个答案:

答案 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)等。