• Tidak ada hasil yang ditemukan

GUIA RAPIDA PARA EL USO DE FORTRAN 1. In

N/A
N/A
Protected

Academic year: 2018

Membagikan "GUIA RAPIDA PARA EL USO DE FORTRAN 1. In"

Copied!
29
0
0

Teks penuh

(1)

Departamento de Ingeniería Mecánica y Mecatrónica

Modelación matemática

Sem I - 2014

GUIA RAPIDA PARA EL USO DE FORTRAN

1. Introducción

El objetivo del presente documento es proporcionar una guía rapida para el uso de Fortran 90/95, para los estudiantes de Modelación Matemática de la Universidad Nacional de Colombia. El documento está basado en un curso virtual de la Universidad de Warwick (UK) 1

. No pretende ser una referencia completa, y por lo tanto cuando se requiera mayor claridad sobre cualquier tópico particular se debe consultar la respectiva bibliografía especializada.

Fortran es un lenguaje de propósito general, pero principalmente orientado a la computación científica. Su principal fortaleza se centra en la realización eficiente de cálculos matemáticos y numéricos para uso y aplicación en diferentes áreas de la ciencia y la ingeniería. Fortran es un acrónimo de FORmula TRANslator, originalmente escrito simplemente como FORTRAN. Fortran fué uno de los primeros lenguajes de programación de alto nivel. El desarrollo de Fortran empieza en la década de 1950 en IBM y han habido varias versiones desde entonces. Por convención, y como medio de identificación, las versiones de Fortran se distinguen por los dos últimos dígitos del año en que se propuso la estandarización respectiva. De esta forma se tienen:

Fortran 66 Fortran 77 Fortran 90 (95) Fortran 2000

Fortran es un lenguaje de programación dominante usado en muchas aplicaciones de ingeniería y mate-máticas, por lo que es importante que se tengan bases para poder leer y modificar cualquier código de Fortran. Algunas opiniones de expertos han dicho que Fortran será un lenguaje que pronto decaerá en popularidad y se extinguirá, lo que no ha sucedido todavía. Una de las razones para esta supervivencia es la inercia del software, ya que una vez que una compañía ha gastado muchos millones de dólares y de años en el desarrollo de software, no le es conveniente traducir el software a un lenguaje diferente, por el costo que implica y por ser una tarea difícil y laboriosa.

1

(2)

2. Formato de Código

La estructura básica de un programa en Fortran 90 (F90) con módulos y funciones2

definidas como unidades internas y dentro del mismo archivo fuente, se indica en la siguiente esquema:

Código ejemplo

module1 module2

program nameOfProgram use module1

use module2

implicit none

constant/variable declarations parameter declarations

data declarations

body of program

contains function1 function2

end program nameOfProgram

La estructura general de un módulo (llamado en el siguiente ejemplo moduloA) corresponde al código presentado a continuación:

Código ejemplo

module moduloA (parametros)

local variable declarations

contains

body of function code

end module moduloA

La estructura de una función es muy similar, pero no incluirá declaraciones del tipo contains. En tal caso sólo se reemplaza la palabra reservada module por function.

2

(3)

2.1. Nuestro primer código.

Hello World

A continuación encontrará el primer código trivial a realizar usando Fortran. Este código incluye una salida a la terminal. Usando un editor de texto cree un archivo nuevo llamadohello.f90, y a continuación escriba el siguiente texto,

program hello

implicit none

! Este es un comentario

! Este programa escribe "hello world" en la terminal

print*, "hello world!"

end program hello

Una vez escrito el anterior texto, guarde el archivo y cierre el editor.

El archivo anterior es simplemente el código fuente. Ahora se debe compilar este código usando otro programa denominado compilador. En el prompt de su terminal de trabajo escriba:

user@prompt:$ ifort hello.f90 -o hello

Si no existe ningún error, se creará un archivo ejecutable llamadohello. Este archivo binario, o ejecutable, está listo para ser ejecutado desde la terminal. Para ejecutarlo escriba en el prompt de su terminal:

user@prompt:$ ./hello

Notas sobre nuestro primer código:

La primer línea determina el inicio del programa, y define el nombre del mismo. En éste caso el nombre del programa es hello

La segunda línea indica que usted quiere declarar explícitamente el tipo de todas y cada una de las variables o constantes. De lo contrario, usted está dejando al compilador decidir por usted el tipo de variable o constante.

La inclusión de comentarios es importante entodocódigo. En Fortran (F90) los comentarios van precedidos por un signo de exclamación (!). Adquiera el hábito de escribir comentarios útiles en su código.

Cada declaración de una línea en F90 esta limitada a 132 caracteres en total. Para continuar una línea, use un ampersand (&) al final de la linea, y con la nueva línea apareciendo directamente debajo de la que se está continuando. La excepción es cuando se está dividiendo una cadena de caracteres, en cuyo caso se debe comenzar la siguiente línea con un ampersand también.

(4)

3. Variables y constantes

3.1. Tipos de datos

Para declarar constantes o variables en F90, se debe declarar eltipode variable. En F90 solo hay cuatro tipos básicos de variables, as saber:

Tipo dato Ejemplo

En F90 las variables deben ser declaradas en el código antes de ser usadas. La sintaxis de declaración empieza con el tipo, seguido del símbolo ::, y a continuación por una lista de una o más variables, cada una separada por una coma. Ejemplo:

Código ejemplo

integer :: big,small,medium

Esta sentencia declara tres variables del tipo entero, llamadas "big", "small", y "medium".

Existen restricciones en los nombres que se pueden usar para declarar variables en F90: Nombres de variables deberán siempre empezar con una letra del alfabeto.

Sólo en el caso de nombres de archivo o links en linux, puede haber un espacio en el nombre de las variables. En F90 los nombres de variables NO pueden tener espacios, pero se puede usar el guion bajo (underscore).

Evite el uso de caracteres especiales.

F90 no distingue entre mayúsculas y minúsculas, así que los nombres de variables ELEMENT, Element y element harán referencia a la misma variable.

Las variables tambieén pueden tener asignados valores por defecto al tiempo de su declaración, sólo use un signo igual en este caso, ejemplo:

real :: element = 1.3E2

(5)

character(len=12) :: string = ’skywalker’

Si se requiere, espacios en blanco pueden será preservados dentro de una cadena limitada por comillas.

Definiciones tipo parametersiguen un patron similar, ejemplo:

real, parameter :: pi = 3.14159

Las variables tipoparameteralmacenan el valor definido en la inicialización, y este valor NUNCA podrá ser cambiado dentro del programa. Piense en estas variables como parámetros constantes de su programa.

Si se declara una variable sin asignar de inmediato un valor a la misma, siempre se puede asignar su valor más adelante en el código. La instrucción de asignación es un signo de igual (=), de forma que el valor de la derecha del signo de igualdad se almacenará en la variable presentada a la izquierda del signo igual.

Ejemplo de práctica

En el siguiente ejemplo, edite el código existente para incluir algunas declaraciones. Siga como ejemplo el siguiente código:

program hello

implicit none

integer :: special

character(len=12) :: name = ’organa’

special = 5

! print out your variables/constants

print*,special

print*

print*,name

end program hello

Asegurese que su código está compilando correctamente, e imprimiendo el valor adecuado en la pantalla de la terminal.

(6)

Palabras reservadas:

Usted debe asegurarse de que ninguno de sus nombres de variables o constantes sean textos como integer, real, character, etc. Claramente estos son palabras reservadas en F90 y tienen un pro-pósito especial.

4. Entrada y salida

4.1. Salida de datos

Usted ya habrá visto cómo podemos hacer que F90 obtenga una salida de información en formato libre, usando print. La sintaxis de la sentencia print es la siguiente:

Código ejemplo

print*, your_data

Usted ya ha visto en uno de los ejemplos anteriores que para imprimir un texto más el valor de una variable entera, había que incluir una línea como: print*,special.

Ejemplo de práctica

Suponga que usted desea imprimir cuatro variables reales en una línea, pero presentando cada número con 4 posiciones decimales. Si se tratara de imprimir tales n´humeros usando la instrucción de formato de impresión libre (por ejemplo, véase el fragmento de código más adelante) Qué pasa?

Código ejemplo

a1 = 5.67893454 a2 = 4.65124454 a3 = 10.2342454 a4 = 539.40405324 print*,a1,a2,a3,a4

Aunque la salida se ve ordenada, vale la pena notar que cada entrada ocupa 8 espacios, con diferente número de decimales.

Puede cambiar esta presentación utilizando una instrucción de formato. Para ilustrar esto, pruebe el siguiente fragmento de código:

Código ejemplo

(7)

Note que cuando se le dá formato a la salida, la sentenciawrite se utiliza en lugar deprint. Debería también notar que print/write enviara una salida de forma estándar, es decir a la términal X, o a un archivo si ha redireccionado la salida.

Si quiere enviar los datos de salida a un archivo específico, tiene que hacer pocos cambios en su código (esto se indicará más adelante).

La instrucción format en el ejercicio anterior contiene entradas llamadas descriptores de edición (edit descriptors). Los descriptores de edición en este ejemplo imprimirán cada número usando un total de 10 espacios, pero con 4 decimales c/u. Los descriptores de edición en esta declaración de formato contienen repetición. En este caso se podría escribir la instrucción format de manera más compacta como:

Código ejemplo

3 format(4f10.5)

4.2. Ingreso/entrada de datos

En F90 existen comandos que son la contraparte a los previamente discutidos print/write. Uno de ellos es read, el cual puede ser usado para leer o adquirir datos, bien sea desde la terminal o desde un archivo.

En los siguientes ejemplos consideraremos la lectura de datos desde la entrada estándar (es decir, mediante teclado en la terminal o desde algún archivo de datos usando re-direccionamiento). Este comando puede operar usando formato libre o formato definido (como en los casos anteriores). La sintaxis general del formato libre de lectura read es el siguiente:

Código ejemplo

! Esta código de ejemplo permite la lectura desde terminal ! sin ningún formato definido, es decir en formato libre read*, your_data

Ejemplo de práctica

(8)

program getname

implicit none

character(len=100) :: name

! Solicite ingreso del nombre desde la terminal

print*,"please enter your name at the prompt"

! Adquiera el texto ingresado

read*,name

! Imprima el texto ingresado en la terminal

print*,"your name is ",name

end program getname

Compile y corra este código como se indicó anteriormente (use ifort o gfort, según el compilador disponible en su sistema). Qué pasa si se escribe un nombre con un espacio? Qué pasa si escribe este nombre entre comillas?

Al igual que con la instrucción write, la instrucción read puede ser modificada para leer datos con formato. Los descriptores de formato para el comandoreadson muy similares a los del comandowrite, y pueden ser consultados en cualquier guía o libro de F90.

La forma en la que se puedenobtener datos de entrada desde óenviar datos de salida hacia un archivo específico (en lugar de la interacción con teclado a través de la terminal) son un poco diferentes. Primero debe abrir el archivo con la instrucción open. La declaración open especifica el número de unidad del archivo (un identificador interno para fortran), el nombre del archivo y el estado del archivo (nuevo/existente/desconocido3

.

Cuando usted necesite enviar datos al archivo definido con la instrucciónfor, se debe indicar el número de la unidad al comando write. Finalmente, el archivo debe cerrarse con una declaraciónclose. Para mayor ilustración pruebe el siguiente ejemplo,

3

(9)

Ejemplo de práctica

En este ejemplo usted creará un código que va a leer un nombre e imprimirá la salida a un archivo llamadomyname.txt. Cambie alguno de sus archivo existentes.f90de manera que sea igual al siguiente ejemplo.

program getname

implicit none

! Declaracion de variables

character(len=100) :: name

! Presente instrucciones en la terminal

print*,’please enter your name at the prompt’

! Lea el texto ingresado por el usuario

read*,name

! Abra un archivo para escribir el nombre ingresado

open(unit=6,file=’myname.txt’,status=’new’)

! Escriba el texto ingresado al archivo myname.txt,

! y asigne la unidad 6 para este archivo

write(6,*)

"your name is",name

! Cierre el archivo myname.txt

close(6)

! Detengamos TODO antes de salir

stop

! Finalice programa

end program getname

(10)

5. Operadores

Los operadores en Fortran son utilizados para manipular y comparar variables y constantes.

5.1. Operadores Aritméticos

Estos pueden ser aplicados a numéros reales y enteros. Los operandos pueden ser enteros, numéros reales o una mezcla de los dos. Los operadores se resumen a continuación:

Adición +

Substracción

-Multiplicación *

División /

Potenciación **

Sí los operandos, para cualquiera de los operadores indicados son dos enteros, el resultado será también un entero; si al menos uno de los operandos es un numero real, el resultado será un numero real.

Ejemplo de práctica En éste ejemplo usted escribiráun código para realizar diferentes operaciones aritméticas con diferentes valores. Siga el ejemplo ilustrado en el siguiente código.

program getname

implicit none

print*,"the result of 22/4 is",22/4

print*,"the result of 22.0/4.0 is",22.0/4.0

print*,"the result of 15/4*4.0 is",15/4*4.0

end program getname

Compile y corra éste código. La salida debería ser:

user@prompt:$

the result of 22/4 is 5

(11)

5.2. Operadores Comparativos

Para comparar dos variables o constantes enF90 se utilizan operadores comparativos. Estos operadores retornan un valor de 0 o1, con0 significando que la declaración o afirmación es falsa, y 1 significando que es verdadera. Los operadores se resumen a continuación4

:

Los operadores comparativos son muy útiles a la hora de tomar decisiones o en el momento de hacer declaraciones de control (lo que se verá más adelante).

Algo para tener en cuenta: No utilice estos operadores para comparar directamente dos numéros reales, buscando igualdad. Debido la forma en que los computadores tratan a los numéros reales es mejor definir una tolerancia y entonces verificar si la diferencia absoluta es menor que la tolerancia definida, por ejemplo

Código ejemplo

real :: a,b

real, parameter :: tol = 1.0e-06 logical :: same

! compare the value of a and b same = (abs(a-b).lt.tol)

5.3. Operadores Lógicos

Estos operadores trabajan con valores reales y retornan otro valor real. Los operadores se resumen a continuación:

(12)

5.4. Operadores de Caracter

Aquí son mostradas dos operadores de caracteres: El operador concatenación (//) y operaciones con subcadenas substring. Mire los ejemplos a continuación para su uso:

EJEMPLO:Abajo se encuentran algunos ejemplo de operación con cadenas:

Expresión Value

string1 .a

bcdef"

string2 "xyz"

string1 (2:4) "bcd"

string1 (1:1) .a

"

string1 (1) No válido

string1 // string 2 .a

bcdefxyz" string2 (2:3) // string1 (1:2) 2 zab"

5.5. Prioridad de Operadores

Al aplicar muchos operadores juntos en una sola declaración, la evaluación de algunos operadores ocurrirá primero. La lista mostrada a continuación otorga el orden en el cual estas operaciones son efectuadas en Fortran 90, en orden de prioridad descendente:

Potenciación

Multiplicación y división

(13)

6. Condicionales y Bucles

6.1.

if / else / endif

Estas estructuras condicionales le permiten controlar el flujo de su código. La declaraciónifle permite controlar sí un programa entra a una sección del código o no, basado en sí una condición es falsa o verdadera. Hay tres variaciones básicas en la declaración if, con una sintaxis general como:

if ( condición verdadera ) Ejecute está declaración

O usted podría utilizar una declaración en bloque como:

if ( condición verdadera ) then

. Ejecute está declaración

. Ejecute está declaración tambien

. etc... endif

Ambas estructuras ejecutarán únicamente la(s) declaración(es) que se encuentran dentro del if sí la declaración inicial es verdadera.

Si usted quiere ejecutar otro código para el caso en el cual la declaración sea falsa, usted puede usar la construcción if/else if/ else:

if ( condición 1 es verdadera ) then

. Ejecute está declaración si la condición 1 es verdadera else if ( condición 2 es verdadera ) then

. Ejecute está declaración si la condición 2 es verdadera else

. Ejecute está declaración si ninguna de las dos condiciones es vedadera endif

Ejemplo de práctica

(14)

program ageist

implicit none

integer :: age

print*,"Por favor introduzca su edad"

read*,age

if (age.lt.50) then

print*,"Usted es bastante joven!"

else if (age==50) then

print*,"Usted es viejo!"

else

print*,"Usted es en verdad viejo!"

endif

end program ageist

Compile y corra éste código. Intente escribir alguna variación sobre el código.

6.2. Declaración

case

La declaracióncasees otra forma de usar construcciones de decisión enFortran 90. Observe el siguiente ejemplo.

(15)

program numbers

implicit none

integer :: i

print*,"Por favor ingrese un numero"

read*,i

select case (i)

case (:-1) ! i is negative

print*,"El numero es negativo"

case(0) ! only zero

print*,"El numero es cero"

case(1:9) ! i is positive

print*,"El numero es positivo y menor a 10"

case default

print*,"El numero es positivo y mayor a 9"

end select

end program numbers

Con la instrucción case usted no está restringido a utilizar valores enteros (integer). Usted podría usar también caracteres. La opción por defecto (default) es completamente opcional.

6.3. Ciclos

DO

/ Bucles

(16)

Código ejemplo

Observe que usted puede introducir una declaración de salida condicional en cualquier parte del cuerpo del bucle, y de esta forma controlar el número de ejecuciones del bucle antes de que ocurra la salida (instrucciónexit). Al poner el condicional al final del bucle se asegura que la declaración se ejecuta al menos una vez.

Una variación en está construcción es usar una declaración de ciclo en vez de una declaración de salida. Está construcción de bucle asegura que cuando la evaluación de condición retornatrue, el bucle pasará sobre el valor del contador del bucle. Ejemplo:

Código ejemplo

Intente códificar lo anterior por usted mismo y ejecutelo. La salida será una impresión de todos los numeros del 1 al 100, a excepción del numero 80, en la terminal.

(17)

Código ejemplo

do <variable> = inicio, final, avance

El avance (o "stride" ) es el intervalo de incremento entre cada iteración, y es opcional. El caso por defecto es un incremento positivo de 1. Note que el"stride" puede ser de igual forma un número positivo o negativo.

Ejemplo de práctica

Ejemplo de un bucle indexado:

program loopy

implicit none

integer :: i

i = 0

print*,"Hacia Adelante"

do i=1, 5

print*,i

end do

print*,"Hacia Atras"

do i = 5, 1, -1

print*,i

end do

end program loopy

Usted no está restringido a un bucle simple o sencillo. Usted podrá necesitará también bucles anidados.

7. Arreglos /

Arrays

7.1. Introducción

Un arreglo en Fortran 90 es una estructura de datos que es usada para almacenar una colección de objetos del mismo tipo. La sintaxis general de la declaración de un arreglo es la siguiente:

Código ejemplo

(18)

El tipo de variable del arreglo es simplemente el tipo de variable de los valores que serán almacenados en el arreglo (por ejemplo reales, enteros etc). El comandoDIMENSION determina el rango del arreglo y es por lo tanto obligatorio. El valor extent es el rango de las entradas del arreglo, lo que determina los subíndices de sus elementos. La sintaxis general para la definición de este rango es

Código ejemplo

entero_inicio : entero_final

Los enteros de definición del rango del arreglo pueden ser positivos, negativos o cero. No es necesario definir el valor de inicio del rango, ya que Fortan 90 asumirá que el primer valor es 1. Un elemento de un arreglo puede ser accedido en el código mediante la siguiente sintaxis:

Código ejemplo

array_name1( expresión de entero )

donde la expresión del entero puede ser tan simple como un solo número entero, o puede ser una expresión para evaluar, por ejemplo i + 1, dondeiserá un contador, es decir una variable tipo entero.

Ejemplo de práctica

Este ejemplo muestra un caso concreto de declaración de un arreglo:

program createArray

implicit none

integer

::

i

integer, DIMENSION( -2 : 2 ) :: arrayA

do i = -2, 2

arrayA(i) = i

enddo

print*, arrayA

stop

end program createArray

(19)

PRECAUCION!

Usted siempre deberá tener cuidado de no referenciar elementos que se encuentren por fuera del rango del arreglo declarado - en el ejemplo de arriba esto sería equivalente a intentar acceder a arrayA(-3) o

arrayA(3). Si usted intenta escribir algo enarrayA(-3)en éste ejemplo, esto sería escrito en una posición aleatoria de memoria, lo que podría ocasionar que sucedieran sucesos impredecibles! Seguramente el programa colapsará, o incluso el compilador se rehusará a compilar tal código. Note que si usted realiza un error de este tipo en su código, y no se toman las opciones adecuadas, el compilador no será capaz de reconocer el error en el momento de la compilación. Así que tenga mucho cuidado!

7.2. Arreglos Multidimensionales

Es posible crear arreglos multidimensionales en Fortran 90. Por ejemplo, para almacenar una matriz en F90, usted puede declarar un arreglo bidimensional. El ejemplo a continuación es la declaración de una matriz 3 x 3.

Código ejemplo

real, DIMENSION( extent_1, extent_2 ) :: matrix_3by3

(20)

Así, por ejemplo, si usted ha intentado imprimir su arreglo de matriz 3x3 al teclear simplemente:

print*,matrix_3by3

Los elementos aparecerán en la terminal en el orden indicado anteriormente. Pruebe por usted mismo!

Ejemplo de práctica

Codifique las declaraciones abajo mostradas para ver un ejemplo de como asignar valores a los elementos de una matriz de enteros, e imprimir estos elementos en el ordenamiento por columna. Observe el uso de bucles anidados.

program myarray

implicit none

integer :: i,j

integer, DIMENSION (1:3, 1:3) :: matrix_3by3

do i = 1, 3

do j = 1, 3

matrix_3by3(i,j) = (2*i)*(j*j)

enddo

enddo

print*,matrix_3by3

end program myarray

Compile y ejecute este código. Intente escribir algunas variaciones del código.

Como usted ha visto en el ejemplo anterior, usted puede referirse a elementos individuales del arreglo de la misma manera en que se referencian las posiciones de una matriz. Por ejemplo, la instrucción matrix_3by3(1,2) claramente se refiere al elemento en la fila 1 y la columna 2 del arreglo o matriz que este representa

Como en otros lenguajes, enFortran 90 usted también puede referirse a una subsección del arreglo, al suministrar rangos de subsecciones. Mire los ejemplos a continuación.

Para acceder a toda la primera fila de la matrizmatrix_3by3 use cualquiera de las siguientes lineas:

matrix_3by3(1,1:3)

(21)

matrix_3by3(1,:)

La siguiente instrucción hace referencia a toda la segunda columna de la matriz:

matrix_3by3(1:3,2)

o

matrix_3by3(:,2)

Usted también puede referirse a elementos en un arreglo al específicar el "stride". A menos que se especifique, el "stride" siempre será 1. Digamos que usted quiere tomar cada segundo elemento de la matriz matrix_3by3 , empezando por el elemento 1. Esto podría ser hecho especificando:

matrix_3by3(1::2)

o de forma alternativa como

matrix_3by3(::2)

7.3. Operaciones con arreglos

En Fortan 90, usted puede aplicar operaciones globales sobre arreglos. Sin embargo, si más de un arreglo va a ser usado en expresiones o calculos, todos los arreglos usados (o subsecciones de los mismos) deben tener la misma forma, es decir deben referirse al mismo número de filas y columnas. El operador (aritmético, lógico, etc) actuará elemento por elemento. A continuación algunos ejemplos cortos y específicos darán mayor claridad.

Multiplicar todos los elementos de la matriz matrix_3by3 por un numero, por ejemplo 2.5:

matrix_3by3 = matrix_3by3 * 2.5

Inicializar cada uno de los elementos de la matriz matrix_3by3 con el valor de 1.0:

matrix_3by3 = 1.0

Ejemplo de una expresión algebraica que involucra otra matriz (del mismo tamaño) llamadamatrix_2:

matrix_3by3 = 3.0 * matrix_3by3 + (matrix_2)**2

Ejemplo de la multiplicación de 2 matrices.

(22)

Nota: El ejemplo anterior NO corresponde con la "multiplicación de matrices"; esta es una simple multiplicación elemento por elemento. Este último ejemplo podría expresarse como:

matrix_3by3(i,j) = matrix_3by3(i,j) * matrix_2(i,j)

Usted también puede aplicar funciones matemáticas intrínsecas (tales como funciones trigonométricas) a arreglos. En este caso, como en todos los anteriores, la función operará con base en operación elemento por elemento.

7.4. Arreglo - Funciones Especificas

Hay mucho más para descubrir en la manipulación de arreglos en Fortran 90 - en particular existen muchas "funciones de arreglos". Dos de las cuales usted podría encontrar muy útiles sondot_product (efectúa el producto interno de dos arreglos) y matmul (toma el producto de dos matrices - la propia multiplicación matricial). Estas dos funciones, entonces, operan en el sentido estricto de algebra lineal.

Ejemplo de práctica

Codifique el siguiente programa para ver un ejemplo de como usar estos operados específicos sobre arreglos.

(23)

program armanip

implicit none

integer :: i,j,c

integer, DIMENSION(1:3, 1:3) :: matrix_3by3,matrix_2,d

integer, DIMENSION(3) :: a,b

do i = 1, 3

do j = 1, 3

matrix_3by3(i,j) = 2*i*j*j

matrix_2(i,j) = 1.5 * j * (i+1)

enddo

enddo

! create vector a from the first row of matrix_3by3

a = matrix_3by3(1,:)

! create vector b from the second row of matrix_2

b = matrix_2(2,:)

! take dot product of these two vectors

c = dot_product(a,b)

print*,c

! take the real matrix inner product

! of the two matrices

d = matmul(matrix_3by3,matrix_2)

print*,d

end program armanip

compile y corra éste código. Intente escribir algunas variaciones en está código.

(24)

Ejemplo de práctica

Escriba el siguiente programa para ver como funciona el cambio de forma de arreglos (también deno-minado re-shape").

program reshape

implicit none

integer :: i

integer, DIMENSION(1:3, 1:3) :: matrix_3by3

integer, DIMENSION(9) :: a

! assign elements of a to be 1 -> 9

a = (/ (i,i=1,9) /)

! reshape this array, a, into a 3by3 matrix

matrix_3by3 = reshape ( a, (/ 3,3 /) )

print*,matrix_3by3

end program shape

Compile y ejecute este código. Intente escribir algunas variaciones obre este código.

7.5. Arreglos de tamaño dinámico / Allocatable arrays

La ultima área que usted puede encontrar útil con respecto a arreglos son los .Allocatable Arrays". A

veces no es conveniente haber decidido el tamaño del arreglo en una línea de compilación. Usted puede obtener flexibilidad al usar un arreglo asignable - en éste caso usted declara un arreglo al especificar el rango (número de dimensiones) unicamente. Su declaración debe incluir la palabra allocatable.

En el cuerpo del código, usted debe asignar la memoria de su arreglo, y una vez usted finalice esta tarea, liberar la memoria mediante la deasignación de la memoria. Esto será más claro con el siguiente ejemplo.

Ejemplo de práctica

(25)

program dynamic

implicit none

integer :: i,j

integer, DIMENSION (:,:), allocatable :: matrix

print*,&

&"Please enter the desired dimensions of your matrix"

read*,i,j

allocate ( matrix(0:i-1,0:j-1) )

matrix = 1.0

print*,matrix

deallocate ( matrix )

end program dynamic

Compile y ejecute este código. Intente escribir algunas variaciones obre este código.

8. Unidades de programa y procedimientos

8.1. Definición de módulo

En F90 una unidad de programa puede ser el cuerpo principal de un programa (iniciado por la sentencia program, como se ha visto en la parte inicial de cada código que se ha presentado hasta ahora), así como también lo puede ser un módulo.

Unmóduloes un elemento usado en proyectos de códigos grandes que involucran varias personas. Los módulos realizan muchas funciones:

Los módulos proporcionan una ubicación central de constantes y variables, de manera que las declaraciones de estos objetos no tengan que repetirse en muchos lugares dentro del código. Esto es equivalente a proporcionar declaraciones globales.

Los módulos pueden ser usados por todo un grupo de subprogramas agrupados.

(26)

Un módulo se puede compilar por separado o en conjunto con el programa principal. En todo caso se debe compilar antes de compilar el código principal. Si un módulo se escribe en el mismo archivo fuente que el cuerpo principal del código, entonces el módulo debe estar antes de la declaración del programa. Un módulo es invocado en el código principal mediante la sentenciause. Módulos y programas pueden contener procedimientos del programa (ver más adelante).

Ejemplo de práctica

Escriba las siguientes sentencias en un archivo nuevo. Este es un ejemplo trivial del uso de un módulo en un programa (llamado area ) En donde el módulo myconstants define algunas constantes:

! declare your module

module myconstants

implicit none

real, parameter :: pi=3.1415927, ee=2.7182818

end module myconstants

! start the main body of code

program area

! include your module with the *use* statement

use

myconstants

implicit none

real :: radius, result

print*,"Please enter the radius of a circle"

read*,radius

result = pi * radius**2

print*,"the area of the circle is ",result," units"

end program area

Compile y ejecute este código. Intente escribir algunas variaciones obre este código.

8.2. Definición de Subrutinas y Funciones

(27)

Una subrutina es una sección de código, identificada con un nombre particular, y que realiza una tarea determinada. Las subrutinas pueden ser invocadas desde una unidad de programa. Estas unidades de programación pueden afectar diferentes variables o porciones de memoria. Una función es similar, pero se utiliza para generar una única respuesta, y es invocada por referencia al nombre de la función. La función puede tener cualquier tipo de dato (por ejemplo, entero, real, etc).

A menudo es el caso de que no hay necesidad de escribir un procedimiento por usted mismo, F90 ya tiene muchas funciones intrínsecas, bastante útiles. Además existen muchas librerias numéricas (por ejemplo, NAG, BLAS, LAPACK, ATLAS, etc) que están disponibles. Estas librerias adicionalmente han sido optimizadas para el funcionamiento en plataformas específicas, por lo que serán bastante rápidas - probablemente mucho más rápidas que cualquier cosa que usted pueda escribir por si mismo.

Un procedimiento de programa puede ser declarado y especificado dentro del cuerpo principal del código, o puede ser externo al cuerpo principal de código. Un procedimiento debe tener argumentos (variables o constantes) que deben ser suministrados por otras insrucciones en el programa. Igualmente un proce-dimiento puede contener variables/constantes locales. Estos objetos locales se crean cuando se invoca el procedimiento y se destruyen cuando el programa sale de este procedimiento. Estos objetos locales no conservan los valores entre invocaciones (llamadas). La declaración del procedimiento debe conte-ner marcadores de posición para los argumentos a ser procesados. Estos son usualmente denominados

argumentos temporales. Este proceso se conoce como asociación de argumentos.

Ejemplo de función

Supongamos que en el cuerpo principal de un código vamos a llamar una funcion llamadawork, pasando por ella una variable real llamada a, así:

print*,work(a)

La definición correspondiente, o declaración, de esta función en este código es:

real function work(x)

Entonces, en este ejemplo, la variable temporal o ficticia esx. Cuando el programa ingresa a la función, reemplazará el valor de x por el actual valor dea.

8.3. Argumentos con atributos de intención

Para hacer su código más claro, puede usar algo llamado atributos de intenciónpara los argumentos de su procedimiento (sea este una función o una subrutina). Estos atributos facilitarán el proceso de compilación al indicar explícitamente al compilador cuál es su intención para el argumento temporal. Por ejemplo, si usted quiere que el argumento temporal:

(28)

Sea cambiado y se le asigne un valor diferente al usado anteriormente. En tal caso use la sentencia intent(out).

Debe ser referenciado y ademas cambiado. Para este caso use la sentencia intent(inout). Cuando un procedimiento es definido internamente, la definición del procedimiento debera venir solo despues del final del programa principal. La declaración deberia ser precedida por la sentencia contains.

Ejemplo de función

Escriba el siguiente código - Este le brindará claridad sobre algunos conceptos que se han cubierto en esta sección.

program example

implicit none

real :: x,y, result

print*,"Please enter the lengths of the rectangle"

read*,x,y

!***********************************************

! make a call to the subroutine called area

!---! the "real" attribute makes sure the input numbers

! are real, even if the user puts in integers

!***********************************************

call area(real(x),real(y),result)

print*,"the area of the rectangle is ",result," units"

! here is a list of one (or more) procedure defintions

! this is for internal procedures

contains

! subroutine declaration contains dummy arguments a,b,c

! these will be substituted for x,y,result

! (as taken from the call statement)

subroutine area(a,b,c)

real, intent(out) :: c

real, intent(in) :: a,b

! note the intent attributes of these variables

c = a * b

(29)

Compile y corra éste código. Intente escribir variaciones sobre él.

9. BIBLIOGRAFÍA

Referensi

Dokumen terkait

Berdasarkan Keputusan Panitia Pengadaan Barang/Jasa Sekretariat Daerah Kabupaten Sidoarjo Nomor 027/10.13.4/SS/2011 tanggal 13 Oktober 2011 tentang Penetapan Daftar

Dengan sebutan orang tidak bersalah, Gottwald ingin menyatakan bahwa bukan berarti Ayub tanpa dosa, tetapi menunjuk kepada kehidupan spiritual dan moralnya adalah baik,

Dalam era globalisasi dan ditengah gempuran kecanggihan teknologi informasi pekerjaan seorang pustakawan tidak hanya bersifat teknis tetapi pustakawan dituntut untuk dapat

This research resulted in SWOT analysis to create a marketing strategy and branding of Kemetul Tourist Village in attempt to promote to local tourists especially for in

Berdasarkan konsep tersebut dapat dikemukakan bahwa strategi pemasaran yang akan dilakukan dalam penelitian ini adalah lebih mengarah kepada upaya-upaya apa saja yang harus

[r]

Hubungan tingkat pendidikan formal ayah siswa terhadap prestasi belajar. pendidikan agama islam

Dalam mempertahankan kesejajaran tubuh yang tepat, perawat mengangkat klien dengan benar, menggunakan teknik posisi tepat , dan memindahkan klien dengan aman dari tempat tidur