Работая поэлементно на массиве - PullRequest
0 голосов
/ 02 декабря 2011

Я пытаюсь проверить, возвращают ли мои массивы чепуху, получая доступ к элементам за пределами, в фортране.И я хочу проверить, что эти значения меньше единицы, и если они есть, измените их на единицу.

Это часть моего кода, вызывающая проблемы:

lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/) LastNeighLabel содержитметка кластера (от 1 до n, где n - общее количество найденных уникальных отдельных кластеров) для последнего соседа в направлении x, y, z соответственно.

Когда 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 в зависимости от того, какой элемент вызывает проблему.

Но я не могу придумать, как это сделать, потому что где будут манипулировать только переменные, передаваемые ему, а недругой массив с тем же индексом.Или я не прав?

С удовольствием отредактирую, если это не имеет смысла.

Ответы [ 3 ]

4 голосов
/ 02 декабря 2011

Не обязательно, чтобы Фортран обращался к массивам, начиная с единицы. Любое начальное значение допускается. Если вам удобнее иметь нулевой индексированный массив, объявите массив следующим образом:

real, dimension (0:N-1, 0:M-1) :: array

Или

real, dimension (0:N, 0:M) :: array

и иметь индексы 0 дополнительно для отлова особых случаев.

Возможно, это еще одно решение вашей проблемы, поскольку нулевые значения индекса будут допустимыми.

3 голосов
/ 02 декабря 2011

Другой возможный способ сделать это - создать расширенный массив меток кластера (с индексными границами, начинающимися с 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 голосов
/ 02 декабря 2011

Может быть, вы могли бы использовать функцию?

  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) и т. Д.

...