INTRODUCCIÓN A LA PROGRAMACIÓN FORTRAN J. San Fabián Informática Aplicada a la Quı́mica Departamento de Quı́mica Fı́sica Aplicada Universidad Autónoma de Madrid Primera versión en Latex: 3 Nov 2004 (18 de febrero de 2008) Introducción a la Programación 2 Índice 1. PRIMERA SESIÓN 4 1.1. Editar, Compilar y Ejecutar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.2. Constantes, Variables y Tipos de Datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.3. Funciones Intrı́nsecas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.4. Bucles (DO) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.5. Problemas Adicionales (opcionales) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10 2. SESIÓN SEGUNDA 11 2.1. Decisiones (instrucción IF) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 2.1.1. Introducción de datos por medio de un fichero. . . . . . . . . . . . . . . . . . . . . . 12 2.2. GOTO (la instrucción que debemos evitar) . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 2.3. Ejercicio 1: Ecuación de segundo grado . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 2.4. Problemas Adicionales (opcionales) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 3. SESIÓN TERCERA 15 3.1. Manejo de Vectores y Matrices . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 3.2. Ejercicio 2: Ajuste de una recta por mı́nimos cuadrados . . . . . . . . . . . . . . . . . . . . . 15 3.3. Problemas Adicionales (opcionales) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4. CUARTA SESIÓN 17 4.1. Subprogramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.2. Ejercicio 3: Integración numérica . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 4.3. Problemas Adicionales (opcional) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 Dpto. Quı́mica Fı́sica Aplicada, UAM 3 INTRODUCCIÓN A LA PROGRAMACIÓN FORTRAN Vamos a comenzar cuatro sesiones (10 horas) de introducci ón a la programación y para ello vamos a utilizar el lenguaje de programación FORTRAN. Lea detenidamente y con calma la introducción siguiente. Siempre que aparezca una [C] es que tiene que contestar alguna cuestión. Cuando aparezca una [P] es porque tiene que hacer un programa (editar, compilar y ejecutar) y cuando funcione imprimirlo. Los programas que no tengan la [P] no hace falta sacarlos por la impresora. Los programas impresos, las contestaciones a las cuestiones y los ejercicios 1 a 3, éstos últimos en las sesiones 2a a 4a forman el guión de prácticas que tiene que entregar al profesor en el plazo de una semana desde la terminaci ón de la cuarta sesión de FORTRAN. También encontrará una serie de ejercicios adicionales que en caso de tener tiempo debe incluir en el guión de prácticas (OPCIONAL). Ante un problema estudie detenidamente la información que le proporciona el ordenador e intente resolverlo por sı́ mismo antes de preguntar al profesor. Introducción a la Programación 4 1. PRIMERA SESIÓN 1.1. Editar, Compilar y Ejecutar Los primero que vamos a hacer es escribir, compilar y ejecutar nuestro primer programa en FORTRAN. Para ello siga los pasos siguientes: 1.- (EDITAR) Edite con cualquier editor un fichero llamado prog1.f con el texto de la Fig. 1. En esta figura el editor utilizado es el ”KWrite”, pero puede utilizar el que le resulte más cómodo (kate, vi, ...). Procure escribir el texto lo más literal posible respetando la columna en la que se escribe cada cosa. Salve (guarde) el fichero al disco con el nombre prog1.f Figura 1: Primer programa FORTRAN (prog1.f) editado con el editor Kedit. 2.- (COMPILAR) 1 Ejecute la siguiente instrucción: gfortran prog1.f -o prog1.exe (J− − y) El sı́mbolo final (J− − y) significa que debe pulsar dicha tecla o la tecla Intro para hacer operativa la orden. Si ha escrito bien el fichero prog1.f no debe aparecer ning ún error. Si la compilación produce algún error, lea detenidamente lo que le indica el ordenador, y con esa informaci ón revise (reedite) el fichero prog1.f y vuelva a ejecutar la instrucción anterior. Si no consigue solucionar los problemas por sı́ mismo pregunte a su profesor. 3.- (EJECUTAR) Si la compilación no da ningún error ejecute el comando ls y verá que entre otros tiene en el disco los ficheros prog1.f y prog1.exe. Este último es un fichero ejecutable. Escriba la instrucción siguiente para ejecutar: ./prog1.exe (J− − y) El ”./” antes del nombre del ejecutable (prog1.exe) es necesario en las últimas versiones de linux e indica que el programa ejecutable esta en el subdirectorio de trabajo en el que estamos situados. Si todo ha funcionado, entonces, hemos editado, compilado y ejecutado nuestro primer programa en FORTRAN. En estas cuatro sesiones de prácticas vamos a aprender un poco más sobre la programación FORTRAN. Como puede suponer es una introducción al FORTRAN muy breve, le aconsejo que practique y profundice por su cuenta en la programación pues puede serle muy útil. 1 Compilar consiste en traducir el lenguaje fortran a código máquina que es capaz de entender el ordenador. Esta operaci ón la realiza un programa llamado compilador, en este caso el gfortran. Dpto. Quı́mica Fı́sica Aplicada, UAM 1.2. 5 Constantes, Variables y Tipos de Datos FORTRAN es un lenguaje de programación ”vivo” ya que la mayorı́a de los programas usados por la comunidad cientı́fica están escritos en FORTRAN. Es un lenguaje de alto nivel, es decir, requiere poco conocimiento del hardware y emplea palabra conocidas (normalmente en inglés) que le indican al ordenador lo que tiene que hacer con unas serie de ”objetos” con los que va a trabajar. Figura 2: Tipo de datos utilizados en el lenguaje FORTRAN. les que podemos manejar estarán entre 10−38 y 1038 . El tipo de ”objetos” que va a manejar el ordenador siguiendo las ordenes de nuestro programa son los que se muestran en la Fig. 2. En estas prácticas únicamente vamos a trabajar con números enteros y reales y muy de pasada con caracteres. Por defecto el FORTRAN que estamos usando utiliza 4 bytes (8x4 = 32 bits) para guardar un número entero o un número real. Esto implica que el número entero más grande, en valor absoluto, que podemos usar es el 2147483647. Por otro lado, los números reales tendrán una precisión aproximada de 7 cifras significativas y los números rea- Los datos pueden estar en nuestro programa de dos maneras diferentes, como constantes o como variables (Fig. 3). Las variables son como las memorias de nuestra calculadora de bolsillo y su contenido puede cambiar durante la ejecución del programa. Los números enteros y reales se definen (es decir, se le indica al ordenador que son números enteros o reales) como se muestra en la Fig. 4. Por otro lado también tenemos varios tipos de números enteros y reales, aunque nosotros vamos a utilizar únicamente los que tiene el FORTRAN por defecto y que hemos señalado en la Fig. 3 (defecto). Figura 3: Constantes y variables. Es importante recordar que las variables enteras se definen con nombres que comienzan por I, J, K, L, M o N (I-N). Y variables reales las que comienzan con las demás letras (A-H, O-Z). Figura 4: Definición de enteros y reales. Introducción a la Programación 6 Con estos datos podemos hacer una serie de operaciones b ásicas (Fig. 5). Observa que las operaciones tienen prioridades, es decir la multiplicación y la división siempre se realizan antes que las sumas y restas. Para evitar problemas a este respecto conviene utilizar paréntesis siempre que tengamos dudas, aunque no sea necesario. Figura 5: Operaciones básicas. Una operación básica y a la vez difı́cil de entender cuando la vemos por primera vez es la instrucci ón de asignación. Cuando vemos un signo = debemos entender que se realizan las operaciones que hay a la derecha del signo = y el resultado se guarda en la variable que esta a la izquierda del igual. Por tanto, a la izquierda del = siempre debe haber una variable. Vamos a hacer un programa para repasar los conceptos vistos hasta ahora. EDITE, COMPILE Y EJECUTE el programa prog2.f. Evidentemente, los números de la columna derecha (entre corchetes) sólo sirven para numerar las lı́neas y no hay que escribirlos. [C] DISCUTA brevemente los resultados. Figura 6: Instrucción de asignación. C prog2.f 16 Oct C Autor: .... C conceptos basicos C=====7========================= P1 = 5.3 N1 = 3 P2 = P1 * N1 N2 = P1 * N1 PRINT * , ’ PRINT * , ’ P2: N2: P2 = P2+N1 PRINT * , ’ * 2 P2-NUEVO: STOP END 97 ’, P2 ’, N2 ’, P2 { 1} { 2} { 3} { 4} { 5} { 6} { 7} { 8} { 9} {10} {11} {12} {13} {14} {15} {16} {17} En los programas en fortran, las instrucciones comienzan en la columna 7. Los comentarios (las primeras cuatro lı́neas en los programas anteriores son comentarios) se indican con una C (también podrı́a ser un asterisco *) en la columna 1. Los comentarios son ignorados por el compilador. El programa termina con dos instrucciones que todo programa FORTRAN debe tener (STOP y END). El lenguaje FORTRAN77 (y anteriores) sigue una serie de reglas rigurosas en cuanto a la colocación de las instrucciones (estudie la Fig. 7 detenidamente). Dpto. Quı́mica Fı́sica Aplicada, UAM 7 Figura 7: División de las lı́neas en FORTRAN77. [C] REMPLACE la lı́nea 13 del programa prog2.f por: 1. P2 = (P2 + N1) + 1 2. P2 = N1 / N2 3. P2 = REAL(N1) / REAL(N2) 4. P2 = P2 / 2.0 * N1 5. P2 = P2 / (2.0 * N1) Vuelva a COMPILAR y EJECUTAR cada caso. ANOTE y ANALICE el resultado. Mantenga el mismo nombre (prog2.f) para todos los casos. 1.3. Funciones Intrı́nsecas Las funciones intrı́nsecas son aquellas definidas por el propio lenguaje de programación (por ejemplo el coseno, la raı́z cuadrada, el logaritmo, etc). Están incluidas en las librerı́as del compilador y éste las reconoce de modo automático (ver Tabla 1). A continuación mostramos un programa sencillo que emplea funciones intrı́nsecas. Observa que los argumentos (valores o variables sobre los que se aplica la función) van siempre entre paréntesis y si hay más de uno, separados por comas. CUIDADO: Los argumentos de las funciones trigonométricas van siempre en radianes en vez de en grados. EDITE, COMPILE Y EJECUTE el programa prog3.f. Para saber cuanto vale la variable PI inserte debajo de la instrucción en donde se calcula el valor de PI la instrucción PRINT*, PI y vuelva a compilar y a ejecutar. [C] ¿Para que se utiliza la variable RAD?. Figura 8: Funciones intrı́nsecas. Introducción a la Programación 8 C prog3.f 17 Oct 97 C Autor: .... C Calcula el coseno de 45 grados C y la ra ı́z cuadrada de 36. C ================================ ANG = 45.0 RA = 36.0 C PI = ACOS(-1.0) RAD = PI/180.0 Func. trigonometricas CS = COS (ANG * RAD) RAI= SQRT(RA) PRINT * , CS, STOP END en radianes RAI Cuadro 1: Funciones intrı́nsecas más habituales. Tipo argum. Tipo función (output) Observaciones Funciones ”matemáticas”: SQRT (gen) Real o comp. (1) Raiz cuadrada EXP (gen) Real o comp. (1) Exponencial LOG (gen) Real o comp. (1) Logaritmo neperiano LOG10 (gen) Real (1) Logaritmo decimal Funciones trigonométricas (trabajan en radianes) SIN (gen) Real o comp. (1) Seno COS (gen) Real o comp. (1) Coseno TAN (gen) Real. (1) Tangente ASIN (real) Real. (1) Arcoseno ACOS (real) Real. (1) Arcocoseno ATAN (real) Real. (1) Arcotangente Funciones de valor absoluto y signos ABS (gen) Int. real o comp. (1) Valor absoluto SIGN (genA, genB) Int. o real (1) Devuelve |genA| con el signo de genB. Funciones de conversión INT (gen) Int. real o comp. Int. Devuelve el valor entero truncando los decimales. REAL (gen) Int. real o comp. Real*4 Convierte un no entero en real. Funciones de redondeo y truncación NINT (real) Real Int Devuelve el entero por redondeo. ANINT (real) Real (1) Devuelve un número real sin decimales, redondeado. Función modulo MOD (ganA, genB) Int. o real (1) Devuelve el resto de dividir genA por genB. Funciones de máximos y mı́nimos MAX (genA, genB, ...) Int. o real (1) Devuelve el mayor de los argumentos. MIN (genA, genB, ...) Int. o real (1) Devuelve el menor de los argumentos. (1) Devuelve el mismo tipo de argumento que la entrada. Nombre Dpto. Quı́mica Fı́sica Aplicada, UAM 1.4. 9 Bucles (DO) Queremos sumar los diez primeros términos de la serie siguiente: 10 X 1 SU M A = I I=1 El programa serie1.f hace la suma de los diez términos, sin embargo, es bastante repetitivo. C serie1.f 16 Oct 97 C Serie 1/I C===================== R = 1.0 R = R + (1.0/2) R = R + (1.0/3) R = R + (1.0/4) R = R + (1.0/5) R = R + (1.0/6) R = R + (1.0/7) R = R + (1.0/8) R = R + (1.0/9) R = R + (1.0/10) PRINT * , ’ SERIE: STOP END C bucle1.f 16 Oct 97 C Serie 1/I con un bucle C=========================== R = 1.0 DO I = 2, 10 R = R + (1.0/I) ENDDO PRINT * , ’ SERIE: STOP END ’, R ’, R Imagine como serı́a el programa si quisiéramos el sumatorio de los 100 o 1000 primeros términos de la serie. Para evitar la repetición del mismo tipo de instrucciones, el FORTRAN tiene la instrucci ón DO. Con esta instrucción el programa anterior se simplifica como puede ver en el programa bucle1.f. La instrucci ón DO I = 2, 10 se entiende como ”hacer desde I igual a 2 hasta I igual a 10 el conjunto de instrucciones que est án entre el DO y el ENDDO” (ver Fig. 9). [C] En los programas serie1.f y bucle1.f ¿son necesarios los paréntesis?. EDITE, COMPILE Y EJECUTE el programa bucle1.f. A continuaci ón REEMPLACE la instrucción R = R + (1,0/I) por R = R + (1/I), ¿El resultado es el mismo?, ¿Por qué?. Si ahora queremos calcular la suma de los 100 primeros términos tenemos que editar el programa bucle1.f, cambiar el 10 por un 100, volver a compilar y ejecutar. Para evitar el tener que editar y compilar el programa cada vez que queremos cambiar el valor lı́mite de la serie tenemos la instrucción READ (ver el programa buble2.f). Esta instrucción sirve para que el programa lea el contenido de una variable (en este caso la variable N) y lo guarde en memoria. Por tanto, al ejecutar el programa bucle2, el ordenador se quedar á esperando a que tecleemos el valor que queremos que valga N. El programa lee este valor cuando despues de teclearlo pulsamos la tecla intro y lo asigna a la variable N. COPIE bucle1.f a bucle2.f utilizando la instrucción siguiente: cp bucle1.f bucle2.f EDITE bucle2.f y MODIFIQUELO de acuerdo con la figura correspondiente a bucle2.f. COMPILE Y EJECUTE el programa bucle2. Observe la diferencia con respecto a bucle1. C bucle2.f 16 Oct 97 C Serie 1/I con un bucle y numero C de terminos variables. C=================================== PRINT * , ’ Numero de terminos:’ READ * , N R = 1.0 DO I = 2, N R = R + (1.0/I) ENDDO + PRINT * ,’ Terminos: ’,N, ’ Serie: ’,R STOP END { 1} { 2} { 3} { 4} { 5} { 6} { 7} { 8} { 9} {10} {11} {12} {13} {14} {15} {16} Introducción a la Programación 10 ATENCIÓN: el carácter ”+” o cualquier otro situado en la columna 6 indica que dicha lı́nea es continuación de la lı́nea anterior (ver Fig. 7), por lo tanto, en el ejemplo anterior, las lı́neas 13 y 14 equivalen a una sola instrucción: PRINT*, ’Términos: ’,N,’ Serie: ’,R A continuación, ELIMINE la instrucción correspondiente al ”print*, ’ Numero ...” (lı́nea 5) y vuelva a compilar y a ejecutar el programa bucle2.f. ¿Cual es la diferencia?. Figura 9: La instrucción DO, bucle básico. 1.5. [C] [C] [C] Problemas Adicionales (opcionales) Las variables siguientes tienen los valores indicados, B = 6,0, C = 4,0, M = 5, N = 3 y K = 2. Indique que valores se almacenarán en la variable J (entera) como resultado de las siguientes operaciones: a) J = M + N/K; b) J = C + B/K + N ; c) J = M − M/K ∗ K; d) J = N ∗ N ∗ ∗K. Programe (sobre papel) las siguientes asignacionesq aritméticas: 2 π a) AREA = 2·P ·R·sen ρ b) ARC = 2 y 2 + 4X 3 c) S = − cos4 x x e) Z = 2 − √x21−a2 − √ 2a2 2 3 3( x −a ) 1/2 x+1 −x g) Y = (2π) 1+senx d) G = 21 log 1−senx ·x [C] √x 2 x “√ ” cos x/2+ π 8 √ 2πx ·e De los siguientes nombre, ¿cuáles son validos como variables enteras, cuáles como variables reales y cuáles no son validos como variables?. Siempre suponiendo que no hay ninguna instrucci ón de especificación previa y considerando la norma del FORTRAN 77. H I 12G [C] f) B = e BETA X+2 ALPHA324 42G I A*B IT* GAMMA LARGA IBM360 F(3)21 COBOL CHI AI COS F1.4 La ”secuencia de Fibonacci” (Leonardo de Pisa 1202) nos darı́a el crecimiento de pares de conejos sobre sucesivos perı́odos de tiempo suponiendo que ningún conejo muere. Los dos primeros términos de la serie de Fibonacci son ambos un uno. Los restantes términos de la serie se calculan sumando los dos términos precedentes. Escriba un programa que lea un valor entero (NMAX) y que calcule y escriba los primeros NMAX términos de la serie de Fibonacci. Escriba un programa en FORTRAN para calcular 1 − 2 + 3 − 4 + 5 − 6 + ... − 1000 Dpto. Quı́mica Fı́sica Aplicada, UAM 11 2. SESIÓN SEGUNDA 2.1. Decisiones (instrucción IF) En determinadas ocasiones un programa debe determinar por sı́ mismo si realiza o no un conjunto de instrucciones concretas. Para ello el FORTRAN utiliza la instrucci ón IF que podemos traducir como el ”si” condicional. Si una determinada condición es cierta, entonces, ejecuta la instrucción (o conjunto de instrucciones). Si no (else) es cierta, entonces hace otra cosa. En la Fig. 10 se muestran tres formas de utilizar esta instrucción. La expresión lógica o condición es una comparación de cuyo resultado determina, el programa, si realiza o no las instrucciones correspondientes. En el programa if1.f se utiliza la primera forma de la instrucción IF para evitar un error al hacer la raı́z cuadrada de un número negativo, estudie este programa (ver Tabla 2) y después compárelo con los programas if2.f e if3.f, que emplean la segunda y tercera forma de la instrucción IF, respectivamente. Figura 10: Tres posibilidades de la instrucción IF. EDITE, COMPILE y EJECUTE los tres programas. Cuando ejecute los programas, el ordenador se quedará esperando a que introduzca los valores de A y B para leerlos, ya que es esta la primera instrucci ón de los tres programas. Teclee ambos valores separados por uno o varios espacios en blancos (barra espaciadora) y pulso intro. No use las flechas de los cursores para avanzar y/o retroceder. C if1.f 17 Oct 97 C Instruccion IF C====================== READ * , A, B C = A - B IF(C.LE.0.0) C = -1.0 * C D = SQRT(C) PRINT * , A, B, C, D STOP END C if2.f 17 Oct 97 C Instruccion IF C ========================= READ * , A, B C = A - B IF(C.LT.0.0) THEN C = -1.0 * C PRINT * , ’ N. complejo’ ENDIF D = SQRT(C) PRINT * , A, B, C, D STOP END C if3.f 17 Oct 97 C Instruccion IF C ======================== READ * , A, B C = A - B IF(C.GT.0.0) THEN D = SQRT(C) PRINT * , A, B, C, D ELSE D = SQRT(-1.0 * C) PRINT * , ’ N. complejo’ PRINT * , A, B, C, D,’i’ ENDIF STOP END Cuadro 2: Operadores (incluidos lo puntos) utilizados en las comparaciones. Operador Significado .LT. Menor que .LE. Menor o igual que .EQ. Igual a .NE. No igual a .GT. Mayor que .GE. Mayor o igual que Introducción a la Programación 12 2.1.1. Introducción de datos por medio de un fichero. EDITE un fichero llamado, por ejemplo, ”ifdatos.dat” y escriba en él dos números separados por varios espacios en blanco; guarde el fichero y ejecute las instrucciones siguientes: ./if1.exe <ifdatos.dat ./if2.exe <ifdatos.dat ./if3.exe <ifdatos.dat Observa que cuando utilizamos el simbolo ”<” los datos que nos piden los programas y que antes teniamos que introducir con el teclado ahora los lee del fichero ”ifdatos.dat”. También podemos escribir el resultado en un fichero; ejecute la instrucción: ./if3.exe <ifdatos.dat >ifsalida.sal y edite el fichero ”ifsalida.sal” para ver el resultado. Tenga cuidado de no confundir los sı́mbolos ”<” y ”>” pues si se equivoca puede borrar el fichero de datos. Los datos editados en el fichero de datos tiene que estar en la misma posici ón (separados por espacios y/o en diferentes lı́neas) que cuando los tecleamos en la pantalla. No tenemos que incluir comentarios en estos ficheros salvo que el programa fortran lea dichos comentarios. En la sesi ón siguiente utilizaremos con frecuencia la introducción de datos por medio de un fichero. 2.2. GOTO (la instrucción que debemos evitar) Observe el programa num1.f, en el introducimos nuevos elementos: la instrucci ón GOTO y las etiquetas. El GOTO (Fig. 11) significa ”vete a ...”, en este caso ”vete a 10” y el ”10” situado delante de la instrucci ón PRINT es una etiqueta. Observe que las etiquetas tienen que ir siempre entre C num1.f 17 Oct 97 las columnas 1 y 5 (ver Fig. 7). Este programa en C Escribe numeros enteros del 1 al 100 C ===================================== realidad es un modo alternativo de hacer un bucle N = 1 10 PRINT * , N pero sin la instrucción DO. EDITE, COMPILE Y EJECUTE el programa num1.f. N = N + 1 IF(N .LE. 100) STOP END Figura 11: Instrucción GOTO. GOTO 10 Dpto. Quı́mica Fı́sica Aplicada, UAM 2.3. 13 Ejercicio 1: Ecuación de segundo grado Figura 12: Diagrama de flujo para resolver una ecuación de segundo grado. Queremos resolvemos una ecuación de segundo grado: a x2 + b x + c = 0 La solución (las raı́ces) de esta ecuación se obtienen resolviendo la ecuación siguiente: √ −b ± b2 − 4ac x = 2a Al resolver esta ecuación podemos encontrarnos con algunos problemas. El primer problema se da cuando a = 0. En este caso no podemos emplear la ecuación anterior pues al dividir por cero el programa nos dará un error. Evidentemente, en este caso, la ecuación a resolver serı́a −c bx + c = 0 ; x = b Para simplificar hemos supuesto que a y b no valen ambos cero a la vez. El segundo problema es el c álculo de la raı́z. Si su argumento (b2 - 4ac) es negativo la raı́z no tiene solución (dentro de los números reales) y el programa nos darı́a otro error. Conviene que nuestro programa compruebe estas posibilidades y evite los errores. Como vemos la programación se va complicando y conviene estructurar los programas antes de escribirlos en el ordenador. Para ello se utilizan los llamados diagramas de flujo. Un diagrama de flujo (no muy ortodoxo) para resolver la ecuación de segundo grado se muestra en la Fig. 12. Haga un programa que resuelva la ecuación de segundo grado. Ayúdese en el diagrama de flujo y las instrucciones dadas anteriormente. Utilice el programa para calcular las raı́ces de las siguientes ecuaciones particulares. OPCIONAL: Incluir en el programa el caso en el que la soluci ón pueda ser números complejos. 2,2x2 − 4,5x + 0,5 = 0 ; Sol : 1,9275 y 0,1179 3,0x2 + 3,0x + 0,75 = 0 ; 2 1,0x + 2,0x + 1,5 = 0 ; Sol : −0,5 Sol : −1 + 0,707i y − 1 − 0,707i Introducción a la Programación 14 2.4. [C] Problemas Adicionales (opcionales) ¿Que valor quedará almacenado en J al final de las secuencias siguientes? (el tipo de las variables es el correspondiente por defecto). a) 2 [P] [P] [P] M = 9 J = 1 CONTINUE J = J + 1 M = M / J IF (M.GT.0) GOTO PRINT * , J b) 2 Un número primo es aquel que sólo es divisible por si mismo y por la unidad. Teniendo en cuenta que si no existe ningún divisor de un número N entre 2 y (N)1/2 entonces N es un número primo, escriba un programa en FORTRAN para calcular y escribir los número primos menores de 1000. La media geométrica de N números positivos es la n-esima raı́z del producto de los números. Por ejemplo, la media geométrica de 0.5, 4.0 y 13.5 es (0.5*4.0*13.5)1/3 = 3.0. Escribe un programa que pregunte por los números positivos y calcule su media geométrica. El programa debe leer números hasta que el usuario introduzca un número negativo. El examen del espectro del átomo hidrógeno muestra la existencia de series de lineas espectrales, las frecuencias de las dos primeras series se calculan con las ecuaciones, 2 2 Serie de Lyman : f = c · R · 11 − n1 ; n = 2, 3, 4, ... (ultravioleta) Serie de Balmer : f = c · R · [P] DO K = 1, 4 J = 0 DO N = 1, 5 J = J + N ENDDO ENDDO PRINT * , J 1 2 2 − 1 2 n ; n = 3, 4, 5, ... (visible) donde c es la velocidad de la luz (3.0·108 m/s) y R es la constante de Rydberg (1.0967758·107 m−1 ). Escribe un programa FORTRAN para generar las primeras frecuencias de estas dos series. Escriba un programa FORTRAN para calcular el máximo común divisor (MCD) de dos números enteros (M y N) utilizando el algoritmo y diagrama de flujo de la figura y de acuerdo con las siguientes etapas: a) Hacemos que el número M sea mayor que N, es decir si N es mayor que M intercambiamos los dos números. b) Calculamos el resto (R) de dividir M por N. Si el resto (R) es cero entonces N es el MCD. c) Si el resto (R) no es cero damos a M el valor de N y a N el valor de R y repetimos las etapas b) y c). Dpto. Quı́mica Fı́sica Aplicada, UAM 15 3. SESIÓN TERCERA 3.1. Manejo de Vectores y Matrices Tenemos una tabla como la que mostramos en la Fig. 13 con valores X e Y. Para manejar una serie de datos en forma de vector o matriz en FORTRAN se definen variables dimensionadas. En el programa dim1.f lo primero que hacemos es definir o asignar (instrucción DIMENSION) dos variables X y Y que tienen un máximo de 10 elemento cada una. Antes de usar este tipo de variable dimensionada, es necesario definirlas al comienzo del programa para reservar espacio en la memoria del ordenador. El programa lee los valores de X y de Y y los guarda en los vectores X(I) e Y(I) (instrucción READ). Después suma todos los X y todos los Y. Le falta escribir los resultados. C C C C DO I=1,N READ * , X(I), ENDDO Y(I) SX = 0.0 SY = 0.0 DO I=1,N SX = SX + X(I) SY = SY + Y(I) ENDDO EDITE, COMPILE Y EJECUTE el programa dim1.f. AÑADA las instrucciones necesarias para obtener la salida de resultados. Estudie con detenimiento el programa, si no entiende algo pregunte a su profesor. 3.2. dim1.f 17 Oct 97 Autor: .....ps}} Suma los valores de X y de Y ============================= DIMENSION X(10), Y(10) READ * , N STOP END Ejercicio 2: Ajuste de una recta por mı́nimos cuadrados Para ajustar una serie de puntos X e Y a una recta (y=a+bx) por mı́nimos cuadrados utilizaremos las ecuaciones siguientes. Primero definimos SX , SY , SXX y SXY como: SX = n X xi ; SY = i=1 SXX = n X x2i n X yi i=1 ; SXY = n X x i yi i=1 i=1 Con estas definiciones, el corte en ordenadas (a) y la pendiente (b) de la recta (y = a + bx) vienen dados por: a = SY − b · S X ; n Figura 13: Tabla de datos X e Y, representación gráfica y recta ajusta por mı́nimos cuadrados. b = SX · SY − n · SXY SX · SX − n · SXX La desviación cuadrática media del ajuste se define como: sP sP n n ∗ )2 2 (y − y i=1 i i i=1 (yi − (a + bxi )) σ = = n − 2 n − 2 σ = r n X SD2 (yi − (a + bxi ))2 ; con SD2 = n − 2 i=1 Introducción a la Programación 16 Figura 14: Un ajuste de mı́nimos cuadrados se basa en minimizar la suma del cuadrado de la diferencias entre los puntos que usamos en el ajuste (yi ) y los puntos de la recta ajustada (y∗i ). y las incertidumbres del corte en ordenadas (σ a ) y de la pendiente (σ b ) se estima como: r r SXX n σa = σ ; σb = σ n · SXX − SX · SX n · SXX − SX · SX El coeficiente de correlación se puede calcular con la expresión siguiente: r = 2 (SX − SX · SY − n · SXY n · SXX )·(SY2 − n · SY Y ) 1/2 ; SY Y = n X yi2 i=1 [P] Utilizando las ecuaciones anteriores haga un programa que lea N puntos X e Y y ajuste una recta por mı́nimos cuadrados. En la Fig. 13 se dan los resultados para este ejemplo. Las incertidumbres de la pendiente y del corte en ordenadas correspondientes a la última cifra significativa se dan entre paréntesis. De modo similar se pueden definir matrices, por ejemplo con la instrucci ón DIMENSION ARRAY(10,10), B(5,5,5) definimos una matriz llamada ARRAY de 10x10 elementos y otra llamada B de 5x5x5 elementos, sin embargo, esto, como otras muchas instrucciones de FORTRAN, se sale del lı́mite de esta introducción. Para su estudio le remitimos a cualquier libro de FORTRAN. 3.3. [P] [P] [P] Problemas Adicionales (opcionales) Edita y guarda los datos del ejercicio 2 en un fichero. Después ejecuta el programa del ejercicio 2 de modo que utilice los datos del fichero. Escribe un programa que ordene de mayor a menor 25 n úmeros. Lee los números de un fichero y almacénalos en un vector A. El programa debe imprimir los números ordenados del vector. Escribe un programa que intercambie las filas 5 y 8 en una matriz de 10x10 leı́da de un fichero. Escribe la matriz resultante. Haz lo mismo pero intercambiando las columnas 3 y 7. 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 .