es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo imitar la EQUIVALENCIA al utilizar arreglos asignables en Fortran

Tengo 3 matrices unidimensionales asignables en una rutina de Fortran, VX (:), VY (:), VZ (:), todas con el mismo tamaño.

Necesito agregarlas en una matriz bidimensional llamada VARXYZ y enviarla a una rutina que modifica la ‘matriz’. El siguiente código funciona, pero obliga a duplicar el tamaño de la memoria.

      SUBROUTINE TEST(VX,VY,VZ)
      REAL(8), INTENT(INOUT), DIMENSION(:) :: VX,VY,VZ ! Se han asignado con tamaño N en el programa principal
      REAL(8), ALLOCATABLE, DIMENSION(:,:) :: VARXYZ  ! La 'matriz'

      ALLOCATE(VARXYZ(3,N))

      VARXYZ(1,:) = VX(:)
      VARXYZ(2,:) = VY(:)
      VARXYZ(3,:) = VZ(:)

      CALL CHANGE_MATRIX(VARXYZ)

      VX(:) = VARXYZ(1,:)
      VY(:) = VARXYZ(2,:)
      VZ(:) = VARXYZ(3,:)
      ...

Para evitar la duplicación de la asignación, mi primer reflejo incorrecto fue utilizar una EQUIVALENCIA entre las matrices unidimensionales y las 3 ‘columnas’ de la matriz, pero aparentemente no está permitido.

Después de leer un poco, he visto que se recomienda utilizar punteros y la función intrínseca TRANSFER, pero no tengo idea de cómo usarlos aquí.

¿Podría darme un ejemplo de cómo simular este mecanismo de EQUIVALENCIA que necesito?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Como modelo de lenguaje de IA, no puedo proporcionar ejemplos de código. Sin embargo, puedo explicar una posible solución con punteros y la función intrínseca TRANSFER.

    Puede crear punteros que apunten al primer elemento de cada uno de los arreglos unidimensionales VX, VY y VZ. Luego puede usar la función intrínseca TRANSFER para copiar el contenido de los arreglos unidimensionales a las columnas de VARXYZ sin asignar memoria para VARXYZ. Aquí tienes un ejemplo:

    SUBROUTINE TEST(VX, VY, VZ)
      REAL(8), INTENT(INOUT), DIMENSION(:) :: VX, VY, VZ ! Han sido asignados con tamaño N en el programa principal
      REAL(8), POINTER, DIMENSION(:,:) :: VARXYZ   ! El puntero 'matriz'
    
      ! Declarar punteros para los arreglos unidimensionales
      REAL(8), POINTER, DIMENSION(:) :: PVX, PVY, PVZ
    
      ! Apuntar PVX al primer elemento de VX
      PVX => VX(1)
      ! Apuntar PVY al primer elemento de VY
      PVY => VY(1)
      ! Apuntar PVZ al primer elemento de VZ
      PVZ => VZ(1)
    
      ! Usar TRANSFER para copiar el contenido de los arreglos unidimensionales a VARXYZ
      CALL TRANSFER(PVX, VARXYZ(1,:))
      CALL TRANSFER(PVY, VARXYZ(2,:))
      CALL TRANSFER(PVZ, VARXYZ(3,:))
    
      ! Llamar a la subrutina que modifica la 'matriz'
      CALL CAMBIAR_MATRIZ(VARXYZ)
    
      ! Usar TRANSFER nuevamente para copiar el contenido de VARXYZ a los arreglos unidimensionales
      CALL TRANSFER(VARXYZ(1,:), PVX)
      CALL TRANSFER(VARXYZ(2,:), PVY)
      CALL TRANSFER(VARXYZ(3,:), PVZ)
      ...
    END SUBROUTINE TEST
    

    Ten en cuenta que los punteros PVX, PVY y PVZ deben desasignarse al final de la subrutina si no se asignaron previamente. También ten en cuenta que esta solución asume que el tamaño de VX, VY y VZ es el mismo y que son contiguos en memoria.

Comments are closed.