Dpto. Quı́mica Fı́sica Aplicada, UAM 17 4. CUARTA SESIÓN 4.1. Subprogramas La realización de programas complejos se suele hacer dividiendo el programa en trozos cada uno de los cuales realiza una tarea definida. Estos trozos es lo que llamaremos subprogramas. A veces hay un conjunto de instrucciones que se repiten en un mismo programa. Si programamos estas instrucciones en un subprograma, el programa principal únicamente tiene que ”llamar” a dicho subprograma sin repetir las instrucciones. En realidad, las funciones intrı́nsecas que hemos visto anteriormente son subprogramas realizados por el fabricante del compilador. La programación con subprogramas facilita el trabajo del programador dando lugar a una programaci ón más estructurada. En FORTRAN hay tres tipos principales de subprogramas: Figura 15: Subprogramas y funciones. 1. Subrutina (SUBROUTINE). Cuando la tarea a realizar modifica varias variables aunque tambi én se puede usar cuando modifica una sola variable o ninguna. 2. Funciones (FUNCTION). Cuando la tarea a realizar devuelve un único valor escalar. 3. Funciones de proposición. Se suele usar para la programación de pequeñas formulas (no la vamos a usar en esta introducción). Esta forma esta obsoleta. Estos subprogramas realizan tareas independientes y pueden compartir valores (argumentos) con el programa que les ”llama”. Como puedes ver en los ejemplos que mostramos a continuación, el subprograma va después del programa principal, aunque puede ir antes e incluso en un fichero aparte pero nunca puede ir intercalado entre las instrucciones del programa principal (MAIN en ingles). En el caso de la subrutina, se las llama con la instrucción CALL seguida del nombre de la subrutina y en entre paréntesis se escriben las variables o constantes (argumentos) que va a utilizar el subprograma. Figura 16: Estructura de un subprograma y de un programa. La llamada a una función se realiza del mismo modo que con las funciones intrı́nsecas (observa las diferencias entre suma1.f y suma2.f). Cuando se efectúa la llamada a un subprograma, el programa principal cede el control al subprograma, este realizar su tarea y al final devuelve el control al programa principal en la instrucción siguiente al CALL. Las variables modificadas en los subprogramas y que están compartidas con el programa principal quedan también modificadas en el programa principal. Hasta ahora hemos hablado de Introducción a la Programación 18 C suma1.f 17 Oct 97 C Subrutina suma 2 numeros C========================= C Lectura de datos ...... READ * , A, B CALL SUMA(A,B,C) PRINT * , A, B, C CALL SUMA(A,C,D) PRINT * , A,C,D STOP END C ======================== C Subrutina SUMA: C R3 = R1 + R2 C ======================== SUBROUTINE SUMA(R1,R2,R3) R3 = R1 + R2 RETURN END C suma2.f 17 Oct 97 C Funcion suma 2 numeros C======================== C Lectura de datos .... READ * , A, B C = SUMA(A,B) PRINT * , A, B, C D = SUMA(A,C) PRINT * , A,C,D STOP END C======================== C FUNCION SUMA: C SUMA = R1 + R2 C======================== FUNCTION SUMA(R1,R2) SUMA = R1 + R2 RETURN END C C C C C C C C C C C C C C media1.f 17 Oct 97 Calcula la media de los datos de un vector ========================== DIMENSION V(100) Lectura de datos ...... READ * , N DO I=1,N READ * , V(I) ENDDO Llamo a la subrutina MEDIA CALL MEDIA (V,N,RMEDIA) PRINT * , RMEDIA STOP END ========================== Subrutina MEDIA: Z es un vector M es el numero de elementos del vector RM es la media de los elementos ========================== SUBROUTINE MEDIA(Z,M,RM) DIMENSION Z(100) SUM = 0.0 DO I=1,M SUM = SUM + Z(I) ENDDO RM = SUM / M RETURN END programa principal y subprograma, sin embargo, un subprograma puede a su vez llamar a otros subprogramas, siempre que la llamada no sea recursiva, es decir un subprograma no puede llamarse a si mismo. Un subprograma comienza con las instrucciones SUBROUTINE o FUNCTION seguido del nombre y entre paréntesis los argumentos (ver Fig. 16). Los argumentos tienen que ser los mismos en la llamada del programa principal y en el subprograma y, por tanto, aunque pueden cambiar de nombre no pueden cambiar de tipo (reales, enteros, caracteres, ...) ni de orden, es decir en el programa suma1.f A, B y C en la primera llamada a la subroutina son en la subroutina R1, R2 y R3, respectivamente. Las variables dimensionadas hay que volver a definirlas en los subprogramas (DIMENSION). Los subprogramas terminar con la instrucción RETURN que devuelve el control al programa principal (o al subprograma que llamó a la subrutina). Edita compilar y ejecuta los programas suma1.f, suma2.f y media1.f, estudia cuidadosamente como funcionan y las diferencias que hexisten entre ellos. Hay otra forma de compartir argumentos entre el programa principal y los subprogramas y viceversa, es la instrucción COMMON. La declaración COMMON sitúa las variables en una posición de memoria especial a la que tienen acceso las subrutina que contengan el mismo COMMON. Cada COMMON suele llevar asociado un nombre aunque también esta el llamado ”black” COMMON que no tiene nombre. Por ejemplo: COMMON/NOTAS/ JUN(25),SEP(5) es un COMMON de nombre NOTAS que guarda las variables JUN(25) y SEP(25) en una posici ón de memoria a la que pueden acceder las subrutina que contengan el COMMON/NOTAS/ ... Un ejemplo de ”black” COMMON serı́a: COMMON ARRAY(225,2), VEC(7), RR Dpto. Quı́mica Fı́sica Aplicada, UAM 4.2. 19 Ejercicio 3: Integración numérica El valor de una integral definida Z b f (x)dx a viene dado por el área limitado por la curva y=f(x) y el eje de abcisas (x) entre x=a y x=b (Fig. 17). Una estimación del área se puede realizar dividiendo la superficie total en pequeñas porciones y sumado el área de cada porción (Fig. 18). En el método trapezoidal, la superficie de cada porción se aproxima a un trapecio y por lo tanto su área viene dado por la ecuación Figura 17: Representación gráfica de la integral de una función. Ai = h [f (xi ) + f (xi−1 )] 2 Sumando el área de todas las porciones o trapecios, en este caso para un ejemplo con N (no de trapecios) igual a 6, tenemos: IT Figura 18: Integral o área como suma del área de los trapecios IT = Z b a h f (x) dx = 2 " = + + h 2 [f (a) + f (x1 )] h 2 [f (x2 ) + f (x3 )] h 2 [f (x4 ) + f (x5 )] + + + h 2 [f (x1 ) h 2 [f (x3 ) h 2 [f (x5 ) + f (x2 )] + f (x4 )] + f (b)] obtenemos la ecuación que nos da la integral aproximada: f (a) + 2,0 n−1 X i=1 f (xi ) + f (b) # (1) [P] Escriba un programa FORTRAN para integrar numéricamente por el método de los trapecios. Aplicar el programa para calcular la integral siguiente: Z 2 (6x5 − 7) dx IT = 0 Sigua el esquema siguiente: 1. Organizar la lectura de datos (a, b y n). 2. Calcular h como (b-a)/n. 3. Calcular los valores de f(a) y f(b) llamando a la función (ver punto 6). Pn−1 4. Calcular la parte correspondiente al sumatorio. SU M = i=1 f (xi ) con xi = a + i·h. 5. Aplicar la Ec. (1) y escribir los resultados. 6. Programar la función f(x) = 6x5 - 7 como un subprograma de tipo FUNCTION. Introducción a la Programación 20 4.3. [C] Problemas Adicionales (opcional) Un método usualmente empleado para resolver ecuaciones de la forma f (x) = 0 es el m étodo iterativo de Newton, el cual se define por f (xn ) xn+1 = xn − 0 (2) f (xn ) Donde f’(xn ) es la derivada de la función en xn . Escribe un programa que resuelva la iteración arriba indicada. f y f’ debes programarlas como funciones (FUNCTION) separadas. Aplica el programa a resolver una ecuación de la forma x2 − a = 0 (3) para un valor de a cualquiera. [C] [C] [C] Escribe un programa para calcular el valor del seno de un ángulo (en grados) utilizando la aproximación iterativa siguiente: X3 X5 X7 SEN O(X) = X − + − + ... 3! 5! 7! donde X en la ecuación anterior esta en radianes. Calcula el seno de 140o con 5, 10 y 15 términos de la serie anterior. (Por supuesto no se puede utilizar las funci ón intrı́nseca SIN del FORTRAN, aunque si quieres puedes utilizar la función DACOS para calcular π). La formula√ de Stirling nos proporciona un modo alternativo de calcular el factorial de N (N!). La formula es: N ! = 2πN ·N N · exp(−N ) . Escribe un programa que use la formula de Stirling para calcular el factorial desde N igual a 1 hasta 20. Comprueba la precisi ón del resultado comparando con el factorial calculado al modo tradicional. Escribir un programa para calcular la raı́z cuadrada de un número x utilizando la siguiente formula: b= 1 x +a 2 a donde b es una aproximación mejor que a a la raı́z cuadrada de x. La primera aproximación se debe tomar como (1/2)x y el procedimiento se debe repetir hasta que la diferencia entre a y b sea menor de 10−6 .