Inicialización de arreglos de 2 variables Ini es de 4x3 i=1 1

Anuncio
Inicialización de arreglos de 2 variables
INTEGER , DIMENSIÓN (4, 3) : : ini
DO i=1, 4
DO j= 1,3
ini(i, j) = j
END DO
END DO
i=1
1
2
3
i=2
1
2
3
i=3
1
2
3
i=4
1
2
3
j=1
j=2
j=3
Ini es de 4x3
Pero si inicializamos con:
(/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/)
1
1
1
1
2
2
2
2
3
3
3
3
Ini es de 1x12
Aunque los 2 arreglos tienen el mismo numero de elementos, no tienen la misma
forma y no pueden ser usados en la misma operación. Para transformalo está la
función intrínseca RESHAPE
Ej
ini= RESHAPE ((/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/), (/4, 3/)
Convierte al vector 1X12 en una matriz de 4X3 la cual es asignada a ini:

INTEGER, DIMENSION (4,3) : : ini (4,3)=&
RESHAPE ((/1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3/), (/4, 3/)
Buena costumbre:
Cuando se trabaja con matrices conservar su forma. Leerlas y
escribirlas con DO o DO implícitos y al realizar operaciones→
programas mas entendibles.
Matrices y subconjuntos de matrices
Se puede realizar operaraciones aritméticas con dos matrices cuando son
conformes o una es un escalar
Ej
a=
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Para realizar un subconjunto de la matriz a
1
a(1, : ) = [ 1 2 3 4 5 ]
6
a( : , 1)=
11
16
21
a(1: 3, 1: 5: 2) =
1
3
5
6
8
10
11
13
15
Arreglos de mas de 2 dimensiones
Ej 2x2x2
A(1,1,1)
A(2,1,1)
A(1,2,1)
A(2,2,1)
A(1,1,2)
A(2,1,2)
A(1,2,2)
A(2,2,2)
Generalizando para N dimensiones:
El primer subíndice es el que se mueve mas rápidamente, un poco mas lento el
segundo… el último es el más lento de todos.
Esto se debe tener en cuenta para inicializar, leer o escribir…..
Enmascarar : la construcción WHERE
Ej: Queremos calcular el logaritmo a una matriz
DO i=1, ifin
DO j=1, jfin
logval(i,j)= log(valor(i,j))
END DO
END DO
Otra forma:
logva= log (valor)
Pero no tubimos en cuenta si exiistia algun valor negativo o un 0 para la cual la función
LOG no es válida.
Para evitar ese error se deberia programar:
DO i=1,ifin
DO j=1,jfin
IF(valor(i,j) >0.) then
logval(i, j) = LOG(valor(i,j))
ELSE
logval(i, j) = -99999.
END IF
END DO
END DO
A esta asignación se le dice enmascarar
En FORTRAN 90 existe una función que realiza esta asignación: WHERE
[nombre] WHERE ( mask_exp)
Sentencias de asignación del arreglo !Bloque 1
ELSEWHERE [nombre]
Sentencias de asignación del arreglo !Bloque 2
END WHERE [nombre]
Si la expresión mask_exp es verdad se ejecuta el Bloque 1, en caso contrario se
ejecuta el Bloque 2.
Ej
WHERE (valor>0)
logval=LOG(valor)
ELSEWHERE
logval=-99999.
ENDWHERE
El FORTRAN 95 agrega una clausula mas al WHERE
[nombre] WHERE ( mask_exp1)
Sentencias de asignación del arreglo !Bloque 1
ELSEWHERE ( mask_exp2) [nombre]
Sentencias de asignación del arreglo !Bloque 2
ELSEWHERE [nombre]
Sentencias de asignación del arreglo !Bloque 3
END WHERE [nombre]
En los FORTRAN 90/95 también es válido
WHERE(mask_exp) sentencia de asignación del arreglo
Analizar un conjunto de datos de entrada cuyo rango se debe encontrar entre
-1000 y 1000. Si un valor no esta dentro de este intervalo asignarle el valor del
límite inferior o superior según sea su signo.
Usando DO e IF
Usando WHERE
Forall permite aplicar operaciones a elemento por elemento de una matriz o a un
subconjunto , ya sea a través de los índices o/y una expresión lógica. (FORTRAN
95)
En general:
[nombre] FORALL (in1= icom, ifin, incr, [in2= ico, m2, ifin2, incr…..exp_log]
sentencia 1
……..
sentencia n
END FORALL [nombre]
Ej SI se quiere conocer la inversa de una matriz de números reales
FORALL(i=1:n, j=1: m , r(i,j)/=0)
r(i, j) =1./ r (i, j)
END FORALL
FORALL puede representar un DO anidado combinado con un IF
DO i= 1,n
DO j=1,m
IF (r (i, j)/= 0.) THEN
r (i, j)=1./ r (i, j)
END IF
END DO
END DO
Cuando utilizamos las sentencias Do e IF las setencias dentro de ella se realizan
en forma secuencial, en la forma seleccionada por el procesador.
FORALL (i=2:n-1, j=2,m-2)
a( i, j) = SQRT(a( i, j))
b( i, j) = 1./ a( i, j)
END FORALL
Realiza todos a( i, j) y cuando termina hace los b( i, j)
FORALL (in1= icom, ifin, incr, [in2= ico, m2, ifin2, incr…..exp_log] sentencia de asignación
ALLOCATABLE ARRAYS
Hasta ahora el tamaño de los arreglos que hemos utilizado fue declarado junto
con el nombre de la variable.
Ej:
INTEGER , DIMENSIÓN (4, 3) : : ini
Esto se denomina STATIC MEMORY ALLOCATION. El espacio en memoria para
almacenar el contenido del arreglo es siempre el mismo a lo largo de todo el
programa.
En algunos casos, esto puede resultar inconveniente si hay algún arreglo que
interviene en nuestro programa del que no conocemos a priori el tamaño que va a
tener. Para salvar este problema generalmente se definen arreglos muy grandes
que eventualmente permitan ajustarse a muchas situaciones, pero esto puede ser
ineficiente si no utilizamos el tamaño completo de las variables ya que estamos
usando mucha memoria.
Para resolver este problema, se introdujo la DYNAMIC MEMORY ALLOCATION
que permite definir el tamaño de un arreglo durante la ejecución del programa. Esto
hace que podamos adaptar los tamaños de los arreglos al problema específico que
estamos resolviendo en cada caso.
Para permitir que el tamaño de un arreglo sea asignado durante la ejecución del
Programa → el atributo ALLOCATABLE en la declaración de las variables.
REAL, ALLOCATABLE, DIMENSION(:) :: X ! La variable X tiene una sola
dimensión
Este atributo le dice al programa que el tamaño de X no será determinado en el
momento de la declaración sino más adelante. Si bien no hay que especificar el
tamaño, si las dimensiones, esto lo hacemos colocando un “: “.
REAL, ALLOCATABLE, DIMENSION(:,:) :: X !En este otro caso X tiene 2
dimensiones.
Para lograr asignarle un espacio en la memoria y poder utilizar a la variable X
disponemos de la sentencia ALLOCATE.
ALLOCATE ( X(10,20))
Esta sentencia le indica al programa que reserve un espacio de 10 filas por 2
columnas en la memoria para la variable X. A partir de este momento podemos
utilizar la variable X como lo hacíamos antes.
ALLOCATE(X(N,M)) ! Esto también es válido si N y M son 2 INTEGER.
Para liberar el espacio que está ocupado por la variable X en la memoria
⇨ DEALLOCATE
DEALLOCATE ( X )
IMPORTANTE ⇨ después de haber hecho esto no podremos acceder más a la
variable X, su contenido se ha perdido.
EJ: Tipiar y compilar el siguiente programa, ejecutarlo mirando como varía la
memoria utilizada por el sistema con el monitor del sistema de windows.
PROGRAM pepe
REAL, ALLOCATABLE, DIMENSION(:,:) :: X
WRITE(*,*)"Antes de asignar a X espacio en memoria, presione enter"
READ(*,*)
ALLOCATE(X(50000,1000))
WRITE(*,*)"X ya está en la memoria de la máquina, presione enter"
READ(*,*)
DEALLOCATE(X)
WRITE(*,*)"X fue eliminado de la memoria de la máquina"
STOP
END PROGRAM pepe
Descargar