Está en la página 1de 41

Manejo de arreglos (matrices)

en Fortran 90 .
Arreglos en Fortran 90
n  Al igual que en matemáticas un arreglo o
matriz en fortran es un conjunto de
elementos del mismo tipo con una cierta
estructura u ordenamiento
n  Podemos tener arreglos unidimensionales
o vectores (matrices de rango 1), en donde
los distintos elementos se pueden designar
con un solo índice a(1), a(2), …, a(n)
Arreglos en Fortran 90
n  Arreglos bidimensionales A(i,j), donde se
necesitan 2 índices
! a a12 ! a1n $
# 11 &
# a a22 ! a2n &
A = # 21 &
# " " # " &
# am1 am2 … amn &%
"

n  O arreglos k-dimensionales (<= 7) donde se


necesitan k índices: a(i1, i2,..,ik)
Arreglos en Fortran 90
n  Los índices no tienen porque empezar
en 1, así tenemos por ejemplo el vector
a(-10:10) que tiene 21 elementos, o la
matriz a(-1:2, 3:5) que tiene rango 2 y
dimensiones 4*3. La manera de
declarar los vectores y/o matrices es
sentencias del tipo
Arreglos en Fortran 90
n  Vectores:
n  real, dimension (-5:5) :: a, b
n  real, dimension(11) :: c
n  real :: d(-5:5), f(11)
n  integer:: i(11), j(-5:5)
n  character(len=4),dimension(-2:2):: chr
n  character(len=4):: zzz(5), xxx(-2:2)
Arreglos en Fortran 90
n  Matrices
n  real, dimension (-2:2, 4:8) :: a, b
n  real, dimension (5,5):: c
n  real :: f(0:4, -2:2), g(5,5)
n  real, dimension (2,3,4) :: d
Arreglos en Fortran 90
n  Construción de arreglos: la construcción de
arreglos es mediante la orden
n  a= (/ a1, a2, …., an /). Se pueden
construir de diferente forma:
n  Explicita:
n  a(2:5) = (/ 1.2, 2.3, 4.5, -1.0 /)
n  Do implícito
Arreglos en Fortran 90
n  Do implícito
n  a(1:4)= (/ (i, i=1,4) /)
n  b= (/ (sqrt(real(j)), j=1,5 /) (estando b

declarado como un vector real de longitud 5)


n  c=(/ 1.2, 2.3, (sqrt(real(j)),j=1, 3)/)

(estando c declarado como un vector real de longitud 5)


n  d=(/ (i, i=2,10,2) /) (números pares del 2 al 10)
Arreglos en Fortran 90
n  Podemos unir dos arreglos, así por ejemplo si
tenemos los vectores de longitud 4 y 5
n  a= (/ (real(i), i=1,4) /)
n  b= (/ (sqrt(real(j)), j=1,5 /)
n  Podemos formar el vector c de longitud 9 como
n  c= (/ a,b /)
n  Obviamente a,b,c deben ser del mismo tipo
Arreglos en Fortran 90
n  El constructor solo genera arreglos unidimensionales
(vectores). Si queremos utilizar este método para
construir matrices podemos usar la orden reshape.
Por ejemplo
n  a=reshape((/ (i, i=1,9 ) /),(/3,3/))

genera una matriz 3x3


! 1 4 7 $
# &
A =# 2 5 8 &
# 3 6 9 &
" %
Arreglos en Fortran 90
§  Selección de una parte de un arreglo
§  Para seleccionar parte de un vector, se hace de la
forma
§  a(i1:i2:i3), siendo i1 el comienzo, i2 el final e i3
el paso, por ejemplo a(1:10:2) coge a(1), a(3),
a(5), a(7), a(9). El paso puede ser negativo, por
ejemplo a(10:4:-2) coge a(10), a(8), a(6), a(4)
§  a(:i2) indica desde el principio hasta i2
§  a(i1:) indica desde i1 hasta el final
Arreglos en Fortran 90
§  Selección de una parte de un arreglo
§  Los índices se pueden incluir en una variable índice
mediante el constructor de arreglos. Ejemplo
§  indices= (/ 1,4,2,3 /)
§  a(indices) coge a(1), a(4), a(2), a(3), o por
ejemplo
§  indices=(/ (i, i=2,10,2) /)
§  a(indices)
§  coge los índices pares del vector a.
Arreglos en Fortran 90
§  Selección de una parte de un arreglo
§  En el caso de matrices, se siguen las mismas
reglas que en el caso de los vectores, solo que
para cada dimensión
§  a(1:7:2, 2:3), coge (a(1,2), a(3,2), a(5,2),
a(7,2), a(1,3), a(3,3), a(5,3), a(7,3)
! a12 a13 $
# &
# a32 a33 &
# &
# a52 a53 &
# a72 a73 &%
"
Arreglos en Fortran 90
§  Selección de una parte de un arreglo
§  a(7,3)
§  a(1:7:2, :)=

! a11 a12 a13 $


# &
# a31 a32 a33 &
# &
# a51 a52 a53 &
# a71 a72 a73 &%
"
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  Siempre y cuando los arreglos a un lado u otro de la
igualdad tengan la misma dimensión es posible poner
igualdades de la forma
§  a=b. Así por ejemplo si se tiene
§  real, dimension (10) :: a
§  real, dimension (20) :: b
§  Se puede poner a=b(11:20)
§  Tambien a=a(10:1:-1)
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  O bien, por ejemplo
§  b(6:15)=a
§  Lo mismo sucede para matrices.
§  real, dimension(3,3) :: a
§  real, dimension(6,6) :: b
§  a=b(2:6:2, 4:6)
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  En el lado derecho de la expresión puede
aparecer un escalar, en este caso todos los
elementos del vector o matriz toman el valor del
escalar, ejemplo
§  real, dimension (3,3) ::a, b
§  a=1 : todos los elementos de a toman el valor 1
§  b=a-1 : le resta 1 a todos los elementos de a
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  Los operadores binarios +, *, -, / son
llamados elementales esto es actúan
elemento a elemento, esto que significa
que son validas operaciones como
§  real, dimension (5) ::a,b,c
§  c=a+b, c=a*b, c=a-b , c= a/b
§  E incluso lógicas: a>b
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  En el primer caso
§  c= (a1+b1, a2+b2, a3+b3, a4+b4, a5+b5)
§  En el segundo
§  c= (a1*b1, a2*b2, a3*b3, a4*b4, a5*b5)
§  En el tercero:
§  c= (a1-b1, a2-b2, a3-b3, a4-b4, a5-b5)
§  En el cuarto
§  c= (a1/b1, a2/b2, a3/b3, a4/b4, a5/b5)
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  En el último caso
§  (a1 > b1, a2 > b2, a3> b3, a4>b4, a5>b5)
=(true, true, false, false, true)
§  El resultado es llamado una mascara
Arreglos en Fortran 90
§  Expresiones con arreglos.
§  Muchas funciones intrínsecas son también
elementales, por ejemplo
§  real, dimension (5) ::a,b,c
§  b=sin(a)
§  c=exp(b)
§  En el primer caso se calcula el seno de
cada uno de los elementos de a y se
ponen en b. En el segundo de la misma
forma se calcula la exp para todos los b’s.
Arreglos en Fortran 90
§  Algunas funciones intrínsecas interesantes
size(a,dim)
§ 

La función size calcula el numero de elementos del


arreglo a. Si solo se da un argumento nos calcula el
número de elementos de a. Por ejemplo si a es una
matriz 3x3 size(a) nos da 9. El segundo
argumento hace referencia a la dimensión de la
matriz para la cual queremos saber el número de
elementos. Así por ejemplo size(a,1) nos da el
número de filas, size(a,2) el número de
columnas de a.
Arreglos en Fortran 90
§  Algunas funciones intrínsecas interesantes
shape(a,dim)
§ 

La función shape nos da la forma de una


matriz. El resultado es un vector de enteros si a
es una matriz o un escalar si a es un vector.
Ejemplo
real, dimension(3,3) ::a
integer, dimension (2) :: forma
forma=shape(a)
print *, forma (resultado: 3 3)
Arreglos en Fortran 90
§  Algunas funciones intrínsecas interesantes
reshape(a,shape, [order=(/1,2 /)])
§ 

La función reshape nos permite cambian las


dimensiones de un vector o matriz. Ejemplo
real, dimension(3,3) :: a
real, dimension(9) :: b
real, dimension (3,4) :: c
real, dimension (4,3) :: d
a=reshape(b, (/3,3/))
d=reshape(c, (/4,3/))
Arreglos en Fortran 90
§  Algunas funciones intrínsecas interesantes
§  minval(a), minloc(a), maxval(a),
maxloc(a)
Nos calculan el valor mínimo y máximo de la matriz
o vector a y nos dan la localización donde se
encuentra este valor.
n  b=transpose(a): calcula la traspuesta de a

n  x=dot_product(a,b): producto escalar

n  c=matmul(a,b) : producto matricial


Arreglos en Fortran 90
§  Algunas funciones intrínsecas interesantes
sum(a, dim)
§ 

Nos calculan la suma de los valores de a a lo


largo de la dimensión dim. Si no se pone la
dimensión nos suma a, si se pone la dimensión
nos da la suma a lo largo de la dimensión dim.
real, dimension(3,3) :: a
sum(a) (nos suma los elementos de a)
sum(a,1) (nos suma las columnas de a)
sum(a,2) (nos suma las filas de a)
Arreglos en Fortran 90
§  Matrices dinamicas
§  Es posible en F90 usar matrices dinámicas,
esto es matrices cuya asignación de memoria
se haga ‘sobre la marcha’ y no tengamos que
asignarle memoria de antemano. Suponed que
sabeis que un vector tiene 1000 elementos en
vez de asignarle una dimension 1000 desde el
principio podeis poner
Arreglos en Fortran 90
§  Matrices dinámicas
§  real, dimension (:), allocatable :: v
§  integer :: dim
§  print *, ‘ dime las dimensiones’
§  read(*,*) dim
§  allocate(v(dim), stat=allocation_status)
§  if (allocation_status > 0) then
§  Print *, ‘error de asignacion de memoria’
§  Stop
§  end if
§  do i=1,dim
§  read(*,*) v(i)
§  end do
Algunas cosas sobre functions
§  En las functions lo mismo que en la subroutines los argumentos son
de entrada y salida, para indicar que son de entrada CONVIENE
indicar que son del tipo (in), y los de salida que son del tipo (out)
mediante la palabra clave intent, por ejemplo
§  real, function f(x,y)
§  implicit none
§  real, intent (in) ::x
§  real, intent (out) :: y
§  De esta manera si intentamos cambiar la x dentro de la funcion nos
dira que no podemos, y si ponemos la y en el lado derecho de una
igualdad nos dirá que no esta definida.
Algunas cosas sobre functions
§  El resultado de una funcion no hay que asignarlo obligatoriamente al
nombre de la funcion se puede elegir otra variable, en este caso hay
que indicarlo mediante la orden:
§  result(resultado), asi por ejemplo tenemos la orden
§  function pepito(x,y) result(resultado)
§  implicit none
§  real :: resultado
§  ….
§  ….
§  resultado =
§  return
§  end function pepito
Algunas cosas sobre functions
§  Funciones vectoriales o matriciales: Es posible en fortran 90 construir una
function que devuelva como resultado un vector o una matriz. Lo
mostraremos con un vector.
program
! funciones
implicit none
real, dimension (10) :: z, x
integer :: i
INTERFACE ! Mandatory
FUNCTION cuadrado(x)
implicit none
real, dimension (:), intent(in) :: x
real, dimension (size(x)) :: cuadrado
END FUNCTION cuadrado function cuadrado(x)
END INTERFACE Implicit none
x= (/ (sqrt(real(i)), i=1,10) /) real, dimension (:), intent(in) :: x
z=0 real, dimension (size(x)):: cuadrado
z(4:5)=cuadrado(x(4:5)) print *, size(x)
print * , z cuadrado = x*x
stop return
end program funciones end function cuadrado
Algunas cosas sobre functions
§  elemental funciones: Lo mismo que las funciones intrínsecas uno
puede construir funciones que se apliquen a cada uno de los
elementos de una matriz o vector. En este caso se debe añadir al
nombre de la función el apellido o keyword elemental e introducir una
orden elementary function:
Algunas cosas sobre functions
§  elemental funciones:
§  program test_prog
§  implicit none
§  real, dimension(3) :: x = (/ 1.0, 2.0, 3.0 /)
§  INTERFACE ! Mandatory
§  elemental real function square(x)
§  implicit none
§  real, intent(in) :: x
§  end function square §  elemental real function square(x)
§  END INTERFACE §  implicit none
§  print *, square(x) §  real, intent(in) :: x
§  square = x*x
§  end program test_prog §  return
§  end function square
Algunas cosas sobre function/
subroutine
§  Funciones o subrutinas como argumentos de otra function o
subroutine.
§  Es posible usar como argumento de una función o subrutina el nombre de otra
función. Esto va a ser muy útil en nuestro curso pues vamos a implementar
métodos genéricos (por ejemplo el calculo de integrales), que queremos
aplicarlos a funciones cuyo nombre puede variar de una ocasión a otra, por
ejemplo que queramos integrar la función exponencial en un programa y la
función logaritmo en otro con el mismo método de integración. Si no usamos este
procedimiento, la función logaritmo o exponencial (según el caso) se deberían
llamar de la misma forma.
§  Sea pepe(func, x, z) el nombre y argumentos de una cierta función pepe. x,z son
dos variables reales y func hace referencia al nombre de una cierta función.
¿ Cómo declararíamos esto en fortran ?
§  real function integral (func, x,z )
§  real :: x,z, integral, zz
§  Como func es el nombre genérico de una función, en algún punto de la función
integral deberíamos tener la expresión
§  zz=func(x)
Algunas cosas sobre function/
subroutine
§  Funciones o subrutinas como argumentos de otra funcion o
subrutina.
§  ¿Pero que hace func?. Lo que hace func viene determinado por el
programa que llama a pepe. Supongamos que queremos evaluar
una parabola: 3*x**2 + 2*x +3. Y generamos una function parabola
§  real function parabola(x)
§  implicit none
§  real :: x
§  parabola=3*x**2 + 2*x +3
§  return
§  end function parabola
§  Cuando el programa principal llame a integral y quiera usar la función
func como parabola deberemos poner
Algunas cosas sobre function/
subroutine
§  Funciones o subrutinas como argumentos de otra function o
subroutine.
§  En la parte declarativa un sentencia: external
§  external parabola
Y cuando llamemos a la función integral lo haremos con la sentencia
z=integral(parabola, x,y)
Las ordenes cycle/exit
§  Estas sentencias nos permiten salir de un ciclo do veamos sus
diferencias.
§  Suponed que tenéis el siguiente código
§  do i=1, 20
§  x(i) = sqrt(real(i))
§  if (i <= 10) cycle
§  x(i) = 2*i
§  end do
§  El código anterior, hace que x(i) sea igual a la raíz cuadrada de i,
hasta llegar al índice i=10, a partir del cual se hace x(i)=2*i
Las ordenes cycle/exit
Sin embargo, si tenéis el siguiente código
§  do i=1, 20
§  x(i) = sqrt(real(i))
§  if (i == 10) exit
§  x(i) = 2*i
§  end do
§  El código anterior, hace que x(i) sea igual a la raíz cuadrada de i,
hasta llegar al índice i=10, cuando se llega a este índice deja de
calcular y sale del bucle. x(i) solo esta definido para los 9 primeros
índices. Es posible que tengáis índices anidados, que hace exit en
este caso, tenéis varias posibilidades, en este caso conviene
nominar a los bucles.
Las ordenes cycle/exit
Ejemplo:
§  pepe: do i=1, 20
§  juan: do j=1, 30
§  x(i,j) = sqrt(real(i))*j
§  if (j == 10) exit juan
§  x(i,j) = 2*i*j
§  end do juan
§  end do pepe
§  El código anterior, hace que x(i) sea igual a la raíz cuadrada de i
multiplicado por j, hasta llegar al índice j=10, cuando se llega a este
índice deja de calcular y sale del bucle en j pero sigue en el i, sin
embargo si teneis el codigo
Las ordenes cycle/exit
§  pepe: do i=1, 20
§  juan: do j=1, 30
§  x(i,j) = sqrt(real(i))*j
§  if (j == 10) exit pepe
§  x(i) = 2*i*j
§  end do juan
§  end do pepe
§  El código anterior, hace que x(i) sea igual a la raíz cuadrada de i
multiplicado por j, hasta llegar al índice j=10, cuando se llega a este
índice deja de calcular y sale del bucle en i, esto es acaban todos los
bucles. También podéis poner cycle pepe, en cuyo caso se acaba
de hacer el índice j y se sigue con el siguiente índice del bucle en i
Compilar con librerias
§  Es muy usual el tener que compilar con rutinas y funciones que están
en una librería, por ejemplo la librería recipes. Supongamos que
necesitáis la rutina lfit de la librería librecipes.a (las librerias suelen
llevar la extensión .a y comenzar con el prefijo lib). Esta librería se
localiza en el aula de informática en el directorio /usr/local/lib.
Supongamos que nuestro programa se llama prog1.f90 y que
tenemos una rutina de nombre sub1.f90 además de la llamada a la
lfit. ¿qué tenemos que hacer para compilar ?
§  gfortran prog1.f90 sub1.f90 –L/usr/local/lib –lrecipes –o prog1.x
§  La opción –L indica el ‘path’ donde se encuentra la librería
§  La opción –l indica el nombre de la librería (se da por supuesto que
el nombre real empieza por lib y tiene la extensión .a). Otra
posibilidad es:
§  gfortran prog1.f90 sub1.f90 /usr/local/lib/librecipes.a –o prog1.x