PDF de programación - Como pasar matrices como argumentos de subrutinas en FORTRAN 77

Imágen de pdf Como pasar matrices como argumentos de subrutinas en FORTRAN 77

Como pasar matrices como argumentos de subrutinas en FORTRAN 77gráfica de visualizaciones

Publicado el 12 de Julio del 2017
1.060 visualizaciones desde el 12 de Julio del 2017
46,4 KB
9 paginas
Creado hace 16a (18/09/2007)
Como pasar matrices como argumentos de subrutinas en

FORTRAN 77

Pablo Santamaría

v0.1 (Agosto 2006)

1. Planteo del problema

Los vectores y matrices usuales de la matemática son representados en FORTRAN como arreglos. Un
arreglo unidimensional es utilizado para almacenar un vector, mientras que un arreglo bidimensional es
utilizado para guardar una matriz.

En FORTRAN 77 los arreglos tienen que tener un tamaño predefinido al momento de definirlos por
primera vez. De esta manera es usual definir los arreglos de tamaños suficientemente grande como para
contener los vectores y o matrices de nuestro problema. La manera “prolija” de declarar explicitamente
el tamaño de un arreglo es a través de una sentencia PARAMETER. Así el siguiente fragmento de código
define un arreglo unidimensional V para contener un vector de a lo más NMAX elementos reales, y un arreglo
bidimensional A que puede contener una matriz real de a lo más NMAX filas y MMAX columnas, donde fijamos,
para nuestros propósitos NMAX = MMAX = 5.

INTEGER NMAX,MMAX
PARAMETER (NMAX=5,MMAX=5)
REAL V(NMAX)
REAL A(NMAX,MMAX)

Si bien en este apunte nos queremos centrar específicamente con matrices, comenzaremos discutiendo
la situación con vectores para poner en contexto los problemas que surgen cuando pasamos a considerar
matrices.

Supóngamos que queremos escribir una subrutina para imprimir los n primeros elementos de un vector.

La siguiente subrutina cumplirá tal misión:

C
C
C

C

C

SUBROUTINE IMPRIMIR_VECTOR(N,V)
--------------------------------
Primera version (perfectible)
--------------------------------
IMPLICIT NONE
INTEGER N
INTEGER NMAX
PARAMETER (NMAX=5)
REAL V(NMAX)
INTEGER I
--------------------------------
DO I=1,N

WRITE (*,*) V(I)

ENDDO
--------------------------------
END

1

Esta subrutina puede ser utilizada en el siguiente programa, donde utilizamos un arreglo unidimensional

de NMAX componentes para guardar un vector cuya componente i-ésima es i.

C

C
C
C

C
C
C
C

C
C
C

C

PROGRAM TEST
--------------------------------
IMPLICIT NONE
INTEGER NMAX
PARAMETER (NMAX=5)
REAL V(NMAX)
INTEGER I,N
--------------------------------
Inicializamos el vector
--------------------------------
DO I=1,NMAX

V(I) = REAL(I)

END DO
--------------------------------
Pedimos al usuario cual es el número de componentes
a imprimir
--------------------------------
WRITE (*,*) ’Ingrese número de componentes a imprimir’
READ(*,*) N
IF (N.GT.NMAX) THEN

WRITE(*,*) ’Número de componentes excedido’
STOP

ENDIF
--------------------------------
Llamamos a la subrutina
--------------------------------
CALL IMPRIMIR_VECTOR(N,V)
--------------------------------
END

Si bien esto funciona, nótese que el arreglo es dimensionado a 5 en el programa principal (a través
del parámetro NMAX), y nuevamente dimensionado a 5 en la subrutina. Esta codificación no es flexible. Si
queremos trabajar con un arreglo mayor, digamos de 100 elementos, tenemos que cambiar la sentencia
PARAMETER a lo largo del código dos veces. Imaginemos ahora que tenemos varias subrutinas que operan
con el vector codificadas de la misma forma. Para lograr que éstas funcionen correctamente tenemos que
revisar de punta a punta el código y cambiar las correspondientes sentencias PARAMETER. Como nosotros
estamos intentando ser buenos programadores, queremos escribir subrutinas más generales que puedan ser
re-utilizadas sin alterar a las mismas.

Una manera proceder, que nos permite FORTRAN 77, es declarar, en la subrutina, la dimensión del
arreglo unidimensional al tamaño N que queremos usar (valor que es pasado junto con el arreglo como
argumento) en vez del máximo valor asignado en el programa principal. Esta forma de codificación es
conocida como método de arreglos de tamaño “ajustable”. Aplicando este procedimiento a nuestro pro-
blema, la subrutina buscada es como sigue.

C
C
C

SUBROUTINE IMPRIMIR_VECTOR(N,V)
--------------------------------
Segunda version
--------------------------------
IMPLICIT NONE
INTEGER N
REAL V(N)

2

C

C

INTEGER I
--------------------------------
DO I=1,N

WRITE (*,*) V(I)

ENDDO
--------------------------------
END

Ahora esta versión de la subrutina puede ser llamada en el programa principal para cualquier valor de
N (en tanto no sea mayor que NMAX). Sólo es necesario alterar el valor de NMAX en el programa principal en
el caso que el valor asignado en la sentencia PARAMETER no sea suficiente para nuestro problema.

Existe una segunda alternativa que podemos considerar para nuestro problema. Esta consiste en consi-
derar asumido el valor de la dimensión de los arreglos que son argumentos en la subrutina, valor que ha
sido definido en el programa que llama a la subrutina. Para hacer esto, utilizamos el signo asterisco (*) en
la declaración del arreglo unidimensional. Este tipo de codificación es conocido como método de arreglos
de tamaño asumido. Con este método la subrutina es escrita como sigue.

C
C
C

C

C

SUBROUTINE IMPRIMIR_VECTOR(N,V)
--------------------------------
Tercera version
--------------------------------
IMPLICIT NONE
INTEGER N
REAL V(*)
INTEGER I
--------------------------------
DO I=1,N

WRITE (*,*) V(I)

ENDDO
--------------------------------
END

Cualquiera de las dos versiones presentadas de la subrutina cumplen su cometido. Solo debe tenerse
presente que es responsabilidad del programador (o sea, nuestra) de que el arreglo sea definido con una
dimensión mayor o igual que N en el programa que realiza la llamada.

Ahora que hemos discutido como codificar en forma eficiente el uso de arreglos unidimensionales como
argumentos en subrutinas, pasemos al caso de arreglos bidimensionales y veamos si podemos aplicar los
métodos anteriores.

Nos interesa ahora diseñar una subrutina para imprimir las n primeras filas y m primeras columnas de
una matriz dada. Para fijar el problema consideraremos un arreglo bidimensional de dimensiones máximas
NMAX = MMAX = 3, es decir, estamos asumiendo una matriz de trabajo de tres filas por tres columnas, dando
un total de nueve elementos. Asignemos los valores de estos elementos a los numeros enteros consecutivos
comenzando desde la unidad para el primer elemento y recorriendo la matriz por filas. En otras palabras,
tenemos la matriz:

1
4
7




2 3
5 6
8 9




Esto puede hacerse facilmente con el siguiente programa

C

PROGRAM TEST
------------------------------------------------
IMPLICIT NONE

3

C
C
C

C
C
C

C
C
C
C

INTEGER NMAX,MMAX
PARAMETER (NMAX=3,MMAX=3)
REAL A(NMAX,MMAX)
INTEGER N,M,I,J,COUNT
------------------------------------------------
Asignamos valores a nuestra matriz de trabajo
------------------------------------------------
N=3
M=3
COUNT=1
DO I=1,3

DO J=1,3

A(I,J) = REAL(COUNT)
COUNT

= COUNT + 1

END DO

END DO
------------------------------------------------
Testeamos que nuestra matriz de trabajo es correcta
------------------------------------------------
WRITE (*,*) ’MATRIZ DE TRABAJO:’
WRITE (*,*)
DO I=1,N

WRITE (*,*) (A(I,J), J=1,M)

ENDDO
WRITE (*,*)
------------------------------------------------
Aqui vendrá la llamada a la subrutina que imprime
las primeras n filas y m columnas
------------------------------------------------
...
CALL ...
END

La subrutina que queremos llamar en el espacio reservado para tal fin en este programa es tal que, por
ejemplo, para el caso n = m = 2 tiene que imprimir la submatriz 2×2

1

4

2

5

Habiendo entendido lo que hicimos para el caso de arreglos de tamaño ajustable para una dimensión,
resulta evidente que la forma en que intentamos inmediatamente de aplicar para el caso presente de dos
dimensiones es algo similar a lo que sigue.

C
C
C

C

SUBROUTINE IMPRIMIR_SUBMATRIZ(N,M,A)
------------------------------------------------
Primera version (no funcionará!)
------------------------------------------------
IMPLICIT NONE
INTEGER N,M,A(N,M)
INTEGER i,j
------------------------------------------------
WRITE (*,*) ’SUBMATRIZ: ’, N, ’ X ’, M
WRITE (*,*)
DO I=1,N

4

WRITE (*,*) (A(I,J), J=1,M)

ENDDO
RETURN
END

Entonces en el programa principal escribimos la llamada a la subrutina como sigue

N = 2
M = 2
CALL IMPRIMIR_SUBMATRIZ(N,M,A)

Despues de compilar el programa, al ejecutarlo obtenemos la siguiente salida por pantalla:

Matriz de trabajo:

1 2 3
4 5 6
7 8 9

Submatriz:

2 x 2

1 7
4 2

¡Esto no está nada bien! ¿Qué es lo qué está ocurriendo? Por favor, ¡devuélvanme mi dinero! Evidentemen-
te, pasar el arreglo bidimensional con tamaños ajustables para ambos índices no está dando el resultado
buscado. Probemos entonces utilizar el método de arreglos de tamaño asumido. La subrutina sería ahora
como sigue.

C
C
C

C

SUBROUTINE IMPRIMIR_SUBMATRIZ(N,M,A)
------------------------------------------------
Segunda version (no compilará!)
------------------------------------------------
IMPLICIT NONE
INTEGER N,M,A(*,*)
INTEGER I,J
------------------------------------------------
WRITE (*,*) ’SUBMATRIZ: ’, N, ’ X ’, M
WRITE (*,*)
DO I=1,N

WRITE (*,*) (A(I,J), J=1,M)

ENDDO
RETURN
END

¡Esta versión es aún peor! ¡El programa ni siguiera compila! Evidentemente considerar ambos índices del
arreglo bidimensional como dimensiones asumidas tampoco conduce a nada.

En este punto seguramente ya estamos desilusionados y entonces, volviendo sobre la idea en la codifi-
cación original de la subrutina para un arreglo unidimensional, consideramos angustiados la posibilidad de
definir las dimensiones del arreglo en la subrutina igual a las del programa principal. Entonces escribimos
la subrutina como sigue:

SUBROUTINE IMPRIMIR_SUBMATRIZ(N,M,A)

5

C
C
C

C

------------------------------------------------
Tercer versión (no flexible)
------------------------------------------------
IMPLICIT NONE
INTEGER N,M
INTEGER NMAX,MMAX
PARAMETER (NMAX=3, MMAX=3)
REAL A(NMAX,MMAX)
INTEGER I,J
------------------------------------------------
WRITE (*,*) ’SUBMATRIZ: ’, N, ’ X ’, M
WRITE (*,*)
DO I=1,N

WRITE (*,*) (A
  • Links de descarga
http://lwp-l.com/pdf5328

Comentarios de: Como pasar matrices como argumentos de subrutinas en FORTRAN 77 (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad