Fortran: matrices

Las matrices pueden almacenar una colección secuencial de tamaño fijo de elementos del mismo tipo. Una matriz se utiliza para almacenar una colección de datos, pero a menudo es más útil pensar en una matriz como una colección de variables del mismo tipo.

Todas las matrices constan de ubicaciones de memoria contiguas. La dirección más baja corresponde al primer elemento y la dirección más alta al último elemento.

Números (1) Números (2) Números (3) Números (4) ...

Las matrices pueden ser unidimensionales (como vectores), bidimensionales (como matrices) y Fortran le permite crear matrices de hasta 7 dimensiones.

Declaración de matrices

Las matrices se declaran con el dimension atributo.

Por ejemplo, para declarar una matriz unidimensional llamada número, de números reales que contienen 5 elementos, escribe,

real, dimension(5) :: numbers

Se hace referencia a los elementos individuales de las matrices especificando sus subíndices. El primer elemento de una matriz tiene un subíndice de uno. La matriz de números contiene cinco variables reales: números (1), números (2), números (3), números (4) y números (5).

Para crear una matriz bidimensional de números enteros de 5 x 5 denominada matriz, escribe:

integer, dimension (5,5) :: matrix

También puede declarar una matriz con un límite inferior explícito, por ejemplo:

real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix

Asignar valores

Puede asignar valores a miembros individuales, como,

numbers(1) = 2.0

o puedes usar un bucle

do i  =1,5
   numbers(i) = i * 2.0
end do

A los elementos de matriz unidimensionales se les pueden asignar valores directamente usando un símbolo de mano corta, llamado constructor de matriz, como,

numbers = (/1.5, 3.2,4.5,0.9,7.2 /)

please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’

Ejemplo

El siguiente ejemplo demuestra los conceptos discutidos anteriormente.

program arrayProg

   real :: numbers(5) !one dimensional integer array
   integer :: matrix(3,3), i , j !two dimensional real array
   
   !assigning some values to the array numbers
   do i=1,5
      numbers(i) = i * 2.0
   end do
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
   !assigning some values to the array matrix
   do i=1,3
      do j = 1, 3
         matrix(i, j) = i+j
      end do
   end do
   
   !display the values
   do i=1,3
      do j = 1, 3
         Print *, matrix(i,j)
      end do
   end do
   
   !short hand assignment
   numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
   
   !display the values
   do i = 1, 5
      Print *, numbers(i)
   end do
   
end program arrayProg

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

2.00000000    
 4.00000000    
 6.00000000    
 8.00000000    
 10.0000000    
         2
         3
         4
         3
         4
         5
         4
         5
         6
 1.50000000    
 3.20000005    
 4.50000000    
0.899999976    
 7.19999981

Algunos términos relacionados con matrices

La siguiente tabla proporciona algunos términos relacionados con la matriz:

Término Sentido
Rango Es el número de dimensiones que tiene una matriz. Por ejemplo, para la matriz denominada matriz, el rango es 2 y para la matriz denominada números, el rango es 1.
Grado Es el número de elementos a lo largo de una dimensión. Por ejemplo, los números de la matriz tienen extensión 5 y la matriz llamada matriz tiene extensión 3 en ambas dimensiones.
Forma La forma de una matriz es una matriz entera unidimensional, que contiene el número de elementos (la extensión) en cada dimensión. Por ejemplo, para la matriz de matriz, la forma es (3, 3) y los números de matriz es (5).
Talla Es el número de elementos que contiene una matriz. Para la matriz de matriz, es 9 y para los números de matriz, es 5.

Pasar matrices a procedimientos

Puede pasar una matriz a un procedimiento como argumento. El siguiente ejemplo demuestra el concepto:

program arrayToProcedure      
implicit none      

   integer, dimension (5) :: myArray  
   integer :: i
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      

   integer, dimension (5), intent (out) :: a
   
   ! local variables     
   integer :: i     
   do i = 1, 5         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)

   integer, dimension (5) :: a  
   integer::i
   
   do i = 1, 5
      Print *, a(i)
   end do
   
end subroutine printArray

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

1
2
3
4
5

En el ejemplo anterior, la subrutina fillArray y printArray solo se pueden llamar con matrices con dimensión 5. Sin embargo, para escribir subrutinas que se pueden usar para matrices de cualquier tamaño, puede reescribirlas usando la siguiente técnica:

program arrayToProcedure      
implicit  none    

   integer, dimension (10) :: myArray  
   integer :: i
   
   interface 
      subroutine fillArray (a)
         integer, dimension(:), intent (out) :: a 
         integer :: i         
      end subroutine fillArray      

      subroutine printArray (a)
         integer, dimension(:) :: a 
         integer :: i         
      end subroutine printArray   
   end interface 
   
   call fillArray (myArray)      
   call printArray(myArray)
   
end program arrayToProcedure


subroutine fillArray (a)      
implicit none      
   integer,dimension (:), intent (out) :: a      
   
   ! local variables     
   integer :: i, arraySize  
   arraySize = size(a)
   
   do i = 1, arraySize         
      a(i) = i      
   end do  
   
end subroutine fillArray 


subroutine printArray(a)
implicit none

   integer,dimension (:) :: a  
   integer::i, arraySize
   arraySize = size(a)
   
   do i = 1, arraySize
     Print *, a(i)
   end do
   
end subroutine printArray

Tenga en cuenta que el programa utiliza el size función para obtener el tamaño de la matriz.

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

1
2
3
4
5
6
7
8
9
10

Secciones de matriz

Hasta ahora nos hemos referido a la matriz completa, Fortran proporciona una manera fácil de referir varios elementos, o una sección de una matriz, usando una sola declaración.

Para acceder a una sección de matriz, debe proporcionar el límite inferior y superior de la sección, así como un paso (incremento), para todas las dimensiones. Esta notación se llamasubscript triplet:

array ([lower]:[upper][:stride], ...)

Cuando no se mencionan los límites superior e inferior, el valor predeterminado es la extensión que declaró, y el valor de paso predeterminado es 1.

El siguiente ejemplo demuestra el concepto:

program arraySubsection

   real, dimension(10) :: a, b
   integer:: i, asize, bsize
   
   a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
   a(8:) = 0.0  ! rest are 0.0 
   b(2:10:2) = 3.9
   b(1:9:2) = 2.5
   
   !display
   asize = size(a)
   bsize = size(b)
   
   do i = 1, asize
      Print *, a(i)
   end do
   
   do i = 1, bsize
      Print *, b(i)
   end do
   
end program arraySubsection

Cuando se compila y ejecuta el código anterior, produce el siguiente resultado:

5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
5.00000000    
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010    
2.50000000    
3.90000010

Funciones intrínsecas de matriz

Fortran 90/95 proporciona varios procedimientos intrínsecos. Se pueden dividir en 7 categorías.