Fortran 90

November 23, 2016 | Author: Glenn Robert Revolledo Vilchez | Category: N/A
Share Embed Donate


Short Description

Download Fortran 90...

Description

Apuntes de Fortran 90

V. Dom´ınguez y F.J. Sayas Junio de 2001

1.

Introducci´ on

Fortran 90 es una actualizaci´on de Fortran 77 que moderniza este lenguaje, incorporando algunas de las caracter´ısticas comunes de los lenguajes m´as modernos (C, C++, Pascal,etc.). Con el nuevo lenguaje se persiguen los siguientes objetivos: Modernizar la sintaxis. Incluir aspectos de programaci´on modular, recursividad,. . . Mejorar la “habilidad” para trabajar con las matem´aticas. Incorporaci´on de estructuras de datos y de punteros. Dentro de los posible se mantiene todav´ıa v´alida las instrucciones y sintaxis del Fortran 77. As´ı peque˜ nas modificaciones permiten pasar un c´odigo en Fortran 77 a un c´odigo en Fortran 90. Sin embargo con ello perdemos las principales ventajas que incorpora el nuevo lenguaje. Cap´ıtulo aparte merece el caso del manejo de tablas. En nuestro caso nos concentraremos en tablas unidimensionales y bidimensionales que se identifican con vectores y matrices. La nueva filosof´ıa de Fortran 90 consiste en el manejo de estas estructuras globalmente en lugar de elemento a elemento. Por u ´ltimo conviene se˜ nalar que existe una actualizaci´on posterior que se conoce como Fortran 95. Sin embargo los cambios que incorpora son de una magnitud sensiblemente inferior a los desarrollados en la versi´on anterior Primeras ideas sobre la sintaxis. se emplea desde la columna inicial, a diferencia del Fortran 77 que dejaba las 6 primeras libres para etiquetas y control de bucles. No se distingue entre may´ usculas y min´ usculas. Hay compiladores que distinguen para los nombres de variables. ! indica una l´ınea de comentario. Todo lo que sigue no se compila. & se emplea para cortar una l´ınea. Se escribe al final de la l´ınea cortada y al principio de la siguiente. Estructura del programa. program nombre programa declaraci´on de variables cuerpo del programa end program nombre programa Ejemplo ! mi primer programa en FORTRAN 90 program primero implicit none real :: x,y

! arranque del programa ! declaraci´ on variables

! programa print*,’dame dos numeros reales’ read*,x,y print*,’su suma es’,x+y print*,’Esta es una linea partida en dos’,& & (x+(2*y)*x-y*y)/3.5 end program primero

! final

2

2.

Declaraci´ on de variables y asignaci´ on Tipos de constantes y variables: • enteras (integer) • de coma flotante (real) a simple y doble precisi´on • complejas (complex) a simple y doble precisi´on • car´acter (character) • l´ogicas (logical): u ´nicamente pueden adoptar los valores .TRUE.

.FALSE

La orden implicit none cancela un convenio impl´ıcito de declaraci´on de variables y obliga a declarar todas las variables Por defecto real y complex son de precisi´on simple, pero depende del compilador. Ejemplo program asignaciones implicit none integer :: i,j real (kind=4) :: x,y ! declara variables de precisi´ on simple real (kind=8) :: z,t ! precisi´ on doble complex :: u ! complex(kind=4) :: u character (len=4) :: palabra ! (len=4) indica que tiene 4 caracteres logical :: test x=3.23e-4 ! asignacion de 3,23 10−4 y=-2.312e2 x=3.4 y=4 ! esta asignaci´ on incluye una conversi´ on de entero a real z=3.23e-4 8 ! 8 indica que es doble precisi´ on t=2. 8 z=(3.e-1,2.) ! =0,3 + 2ı palabra=’casa’ ! las comillas identifican las constantes car´ acter palabra="Juan" ! tambi´ en se usan las dobles comillas test=.TRUE. end program asignaciones

Inicializaci´ on de variables. Se pueden dar valores de arranque a las variables al declararlas parameter bloque la posibilidad de reasignar la variable en el transcurso del programa En las asignaciones de inicializaci´on no puede haber operaciones aritm´eticas. Es aconsejable que no haya conversiones autom´aticas (entero a real, etc).

3

programa asignaciones implicit none real :: x=4.,t,z=3.e-2 real (kind=8) :: u=6.e2 8 complex :: a=(2.,3.) character (4) :: palabra=’casa’ real, parameter :: pi=3.141592 ...

3.

! asigna valores de arranque a x y z

! (4) abrevia (len=4)

Lectura y escritura en pantalla

Para escribir en pantalla y leer de teclado, en formato libre, se usan respectivamente print*,

read*, Ejemplo

... x=3.5 print*,’x es ’,x print*,’da un valor a y’ read*,y print*,’valores de x e y’,x,y ...

4.

Operaciones num´ ericas

Binarias b´ asicas. Suma, resta, producto, divisi´on y exponenciaci´on. +

-

*

/

**

entero entero real doble

real real real real

doble doble real doble

Tabla de tipos de datos y resultado. entero real doble

Funciones matem´ aticas b´ asicas. El argumento siempre se escribe entre par´entesis. abs (valor absoluto o m´odulo) sqrt (ra´ız cuadrada) exp (exponencial) log (logaritmo neperiano) log10 sin cos tan

4

asin acos atan sinh cosh tanh Otras. mod(i,j) da el resto de la divisi´on entera int(x) da la parte entera de x floor(x) da el mayor entero menor o igual que x ceiling(x) da el menor entero mayor o igual que x max(x1 ,...,xn ) da el mayor de dos o varios argumentos min(x1 ,...,xn ) da el menor de dos o varios argumentos Ejemplo program partesEnteras real :: x=2.3, y=-4.3, z=7.2 integer :: i=3, j=7, k=-5

! preasignadas

print*, floor(x), ceiling(x), int(x) print*, floor(y), ceiling(y), int(y) print*, max(x,y,z), min(i,j,k) end program partesEnteras

El programa precedente devolver´ıa en pantalla: 2 3 -5 -4 7.2 -5

5.

2 -4

Estructuras de decisi´ on

Operadores de comparaci´ on. N´otese la diferencia entre el igual de comparaci´on (==) y el de asignaci´on. El s´ımbolo /= indica 6=. >

<

=

5

==

/=

Operadores l´ ogicos. Son cuatro: y, o, o exclusivo, negaci´on. .AND.

.OR.

.XOR.

.NOT.

Simple de sentencia u ´nica if (expresi´on l´ogica) sentencia Simple de sentencia m´ ultiple if (expresi´on l´ogica) then sentencia primera sentencia segunda ... end if If-else if (...) then ... else ... end if Decisi´on m´ ultiple if (...) then ... else if (...) then ... else if (...) then ... else ! puede no estar ... end if Puede haber estructuras anidadas. Ejemplo program decisiones implicit none real :: x,y print*,’escribe x e y’ read*,x,y if (y0) then print*,’x es positivo’ else print*,’x es negativo’ end if if ((x>0 .AND. y>0).OR.(x=0) then print*,’x es negativo’ cycle ! se pasa de nuevo a la primera l´ ınea, incrementando i end if print*,’¿Otra vez? (1->si)’ read*,op if (op/=1) exit ! si op6=1 se sale del bucle end do nombre ! cierre de bucle etiquetado end program repeticiones

7.

Ficheros La instrucci´on b´asica de apertura de un fichero es open(unit=unidad, file=nombreFichero, status=tipo) donde: • unidad es un n´ umero entero que identificar´a al fichero mientras permanezca abierto • nombreFichero es el nombre de fichero que se desea abrir; lleva comillas • tipo es uno de los cuatro siguientes valores ◦ ’old’ cuando el fichero ya existe; permite leer pero no escribir ◦ ’new’ cuando el fichero no existe y se va a crear; si ya existe, da un error ◦ ’replace’ cuando el fichero no existe o existe pero se va a reemplazar por uno nuevo; borra el anterior 8

◦ ’scratch’ cuando se trate de un fichero temporal de trabajo que se borrar´a al cerrar Las instrucciones write(unidad,*) read(unidad,*) sirven para escribir y leer en formato libre. La instrucci´on open dada abre ficheros de tipo texto. Se puede modificar para ficheros binarios (sin formato). El fichero se cierra con close(unidad) Ejemplo program ficheros implicit none real :: a,b integer :: i,n open(unit=1, file=’datos.dat’, status=’old’) open(unit=2, file=’salida.res’, status=’replace’) read(1,*) n do i=1,n read(1,*) a,b write(2,*) a+b end do close(1) close(2) end program ficheros

Si el fichero datos.dat tiene la forma 5 4. 6. -2. 1. 2.

2. 3. 4. 1.2e-3 1.1e2

el fichero salida.res tendr´a la forma 6. 9. 2. 1.0012 112.

9

8.

Funciones En principio una funci´on devuelve u ´nicamente un valor. La sintaxis general es function nombre declaraci´on de variables instrucciones return end function nombre nombre es la denominaci´on de la variable de salida y debe estar declarada con las dem´as. Puede haber m´as de un return por funci´on. El final es innecesario. Ejemplo

program programaPrincipal implicit none integer :: i,n real :: x, f ! la funci´ on f se declara como otra variable print*,’inserta numero repeticiones’ read*,n do i=1,n print*,’escribe x’ read*,x print*,f(x) print*,x+f(x) end do end program programaPrincipal function f(y) implicit none real :: y,f,z if (y>=0) then z=y**3 f=z+z**2 else f=0 end if return end function f

9.

! z es una variable local

! f ser´ a el valor de salida

Subrutinas La sintaxis de una subrutina es subroutine nombre(arg1 ,..., argn ) declaraci´on de variables instrucciones end subroutine nombre

10

Todos los argumentos son, salvo que se indique lo contrario mediante los especificadores intent, de entrada y salida, es decir, su valor puede ser modificado en el transcurso de la ejecuci´on. La llamada a una subrutina se realiza mediante la orden call call nombre(var1 ,..., varn ) El especificador intent sirve para bloquear un argumento como argumento de entrada o salida. Sus posibles valores son • in (entrada); no admite que sea modificada • out (salida) • inout (entrada y salida) Se puede regresar al programa principal desde cualquier punto de la subrutina con return. Ejemplo program programaPrincipal implicit none integer :: i,j real :: x,y,z print*,’introducir dos enteros y dos reales’ read*,i,j,x,y call intercambia(i,j) print*,i,j call potencias(x,y,z,i,j) end program programaPrincipal subroutine intercambiar(u,v) integer :: u,v,w ! u,v son de entrada-salida; w es local w=u u=v v=w end subroutine intercambiar ! no hace falta poner un return subroutine potencias(x,y,z,i,j) integer, intent(in) :: i,j ! i,j son argumentos de entrada real :: x,y real, intent(out) :: z if ((iaa ! c apunta a aa d=>bb ! d apunta a bb print*,’aa=’,aa,’bb=’,bb print*,’valor apuntado por c’,c,’valor apuntado por d’,d c=-6 print*,’aa=’,aa,’bb=’,bb print*,’valor apuntado por c’,c,’valor apuntado por d’,d c=>d ! c apunta a bb (a->d->bb) c=2 print*,’bb=’,bb 25

print*,’valor apuntado por c’,c,’valor apuntado por d’,d nullify(c) ! c no apunta a ninguna variable end program puntero

El programa anterior da como salida en pantalla a= 4.000000 b= valor apuntado por c a= -6.000000 b= valor apuntado por c b= 2.000000 valor apuntado por c

6.000000 4.000000 6.000000 -6.000000 2.000000

valor apuntado por d

6.000000

valor apuntado por d

6.000000

valor apuntado por d

2.000000

Las variables punteros pueden definirse para apuntar a estructuras m´as complicadas: arrays y estr´ ucturas de datos.

20.

Ejemplo final

Problema. Almacenamiento (y manipulaci´on) de matrices esencialmente vac´ıas. Modelo sparse. 

 0 1,5 2,5 0  −2 0 0 0,5  0 0,25 0 0 real 1,5 integer 1 integer 2

2,5 1 3

−2 2 1

0,5 0,25 2 3 4 2

El formato debe guardar el tama˜ no de la matriz original m´as el n´ umero de elementos no nulos (por comodidad) Problema pr´ actico. El tipo de datos debe admitir longitudes por determinar. Pero no puede haber nada allocatable: * en la definici´on de un tipo de datos * como argumento de una subrutina o funci´on Sustituir allocatable por pointer y hacer lo mismo. Por dentro, el programa cambia mucho; por fuera, no. Plan. M´odulo con tipo sparse Subrutinas y funciones: • leer matriz sparse • pasar sparse a matriz • pasar matriz a sparse • multiplicar sparse por vector Crear un m´odulo con las interfaces de todo lo anterior Programa de prueba 26

module cosassparse type sparse integer :: nf,nc,nel real, pointer :: matriz(:) integer, pointer :: fil(:), col(:) end type sparse end module cosassparse module funcionessparse interface subroutine leersparse(u) use cosassparse type(sparse) :: u end subroutine leersparse function sparser(v,dim) use cosassparse type(sparse) :: sparser integer,dimension(2) :: dim real :: v(dim(1),dim(2)) end function sparser function matriz(a) use cosassparse type(sparse) :: a real :: matriz(a %nf,a %nc) end function matriz function sparseporvector(a,x,m) use cosassparse integer :: m type(sparse) :: a real :: x(m),sparseporvector(a %nf) end function sparseporvector end interface end module funcionessparse subroutine leersparse(a) use cosassparse type (sparse) :: a integer :: n,i print*,’Numero elementos, filas, columnas’ read*,n,a %nf,a %nc a %nel=n allocate(a %matriz(n),a %fil(n),a %col(n)) do i=1,n read*,a %matriz(i),a %fil(i),a %col(i) end do end subroutine leersparse Nota. a entra sin tama˜ no predefinido y sale con tama˜ no asignado. function matriz(a) use cosassparse type(sparse) :: a real :: matriz(a %nf,a %nc) integer :: i matriz=0. 27

do i=1,a %nel matriz(a %fil(i),a %col(i))=a %matriz(i) end do end function matriz function sparser(v,dim) use cosassparse type(sparse) :: sparser integer,dimension(2) :: dim real :: v(dim(1),dim(2)) integer :: cont,i,j,aux(1) sparser %nf=dim(1) sparser %nc=dim(2) aux=count(v/=0) sparser %nel=aux(1) cont=aux(1) allocate(sparser %matriz(cont), & & sparser %fil(cont),sparser %col(cont)) cont=0. do i=1,dim(1) do j=1,dim(2) if(v(i,j) /= 0) then cont=cont+1 sparser %matriz(cont)=v(i,j) sparser %fil(cont)=i sparser %col(cont)=j end if end do end do end function sparser function sparseporvector(a,x,m) use cosassparse integer :: m type(sparse) :: a real :: x(m),aux(a %nf),sparseporvector(a %nf) if (m /= a %nc) then print*,’error de dimensiones’ return end if aux=0 do i=1,a %nel aux(a %fil(i))=aux(a %fil(i))+& & a %matriz(i)*x(a %fil(i)) end do sparseporvector=aux end function sparseporvector program pruebas use cosassparse use funcionessparse type (sparse) :: a real,allocatable :: bb(:,:),cc(:,:),x(:),y(:) allocate(bb(3,5),x(5),y(3)) 28

do i=1,3 bb(i,i+2)=3.*i bb(i,i)=-1.*i end do a=sparser(bb,shape(bb)) print*,a %matriz allocate(cc(a %nf,a %nc)) cc=matriz(a) do i=1,size(cc,dim=1) print*,cc(i,:) end do print* x=1. y=sparseporvector(a,x,5) print*,y end program pruebas

29

View more...

Comments

Copyright ©2017 KUPDF Inc.
SUPPORT KUPDF