Pregunta

Estoy tratando de verificar si mis matrices están devolviendo tonterías accediendo a elementos fuera de límites, en fortran. Y quiero verificar que estos valores sean menores que uno, y si lo son, cámbielos a uno.

Esta es la parte de mi código que causa problemas:

lastNeighLabel=(/clusterLabel(jj-1,kk,ll), clusterLabel(jj,kk-1,ll), clusterLabel(jj,kk,ll-1)/) LastNeighLabel contiene la etiqueta del clúster (entre 1 y n, donde n es el número total de clústeres separados únicos encontrados) para el último vecino en la dirección x, y, z respectivamente.

Cuando jj o kk o ll son 1, intentan acceder al elemento 0 de la matriz, y cuando FORTRAN cuenta desde 1 en las matrices, intenta destruir el universo. Actualmente estoy en un lío enredado de aproximadamente 8 declaraciones if / elseif tratando de codificar para cada eventualidad. Pero esperaba que hubiera una forma de operar en cada elemento. Entonces, básicamente, me gustaría decir where((/jj-1,kk-1,ll-1/).lt.1) do clusterLabel(jj-1,kk,ll)=0 etc dependiendo de qué elemento está causando el problema.

Pero no puedo pensar en una forma de hacerlo porque donde solo manipulará las variables que se le pasen, no una matriz diferente en el mismo índice. ¿O me equivoco?

Con gusto editaré si esto no tiene sentido.

¿Fue útil?

Solución

¿Quizás podrías usar una función?

  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

y luego use f (clusterLabel, jj-1, kk, ll) etc.

Otros consejos

No es obligatorio que Fortran acceda a las matrices a partir de una.Se permite cualquier valor inicial.Si le resulta más conveniente tener una matriz indexada cero, declare la matriz como:

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

O

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

y haga que los índices 0 sean adicionales para detectar casos especiales.

Esta podría ser otra solución a su problema, ya que los valores de índice cero serían legales.

Otra forma posible de abordar esto es crear una matriz de etiquetas de clúster extendida (con límites de índice que comienzan en 0), que es igual a la matriz de etiquetas de clúster con una capa de ceros clavada en el exterior.Luego puede dejar que su ciclo se ejecute de manera segura sobre todos los valores de jj, kk y ll.Depende del tamaño de la matriz si esta es una solución factible.

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
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top