FAQ Fortran
FAQ FortranConsultez toutes les FAQ
Nombre d'auteurs : 1, nombre de questions : 70, dernière mise à jour : 23 juillet 2021
- Qu'est ce qu'une variable indicée ?
- Comment déclarer une variable indicée ?
- Comment affecter une valeur à une variable indicée ?
- Comment agir sur tout ou une partie d'une variable indicée ? (Fortran90)
- Comment faire des opérations sur des variables indicées ? (Fortran90)
- Comment additionner tous les éléments d'une variable indicée ? (Fortran90)
- Comment multiplier tous les éléments d'une variable indicée ? (Fortran90)
- Comment transposer une matrice ? (Fortran90)
- Comment multiplier deux matrices ? (Fortran90)
- Comment calculer un produit scalaire ? (Fortran90)
Une variable simple correspond à une zone mémoire et contient une valeur. Il est possible de regrouper sous un même nom de variable un ensemble de zone mémoire et donc un ensemble de valeurs. Chaque valeur (ou zone mémoire) de la même variable est alors repérée par un indice.
Ces variables sont, par exemple, des listes (variables à un indices) ou des tableaux (variables à 2 indices) etc ... Elles sont très largement utilisées dans les programmes.
Pour déclarer une variable indicée, il faut préciser son type (entier, réel, chaîne de caractères ...) et sa dimension, c'est à dire le nombre d'éléments qu'elle contient.
Pour ce qui est de la dimension, depuis Fortran90 on a deux possibilités : une déclaration statique ou dynamique. Dans une déclaration statique, la dimension de la variable est donnée au départ et est fixée pour le reste du programme. A l'exécution du programme une zone mémoire dont la taille dépend de la dimension est réservée pour toute la durée de l'exécution.
! une liste d'entier
integer
,dimension
(1:10)::liste
! un tableau de réel double précision
double
precision
,dimension
(1:10,-5:5)::tableau
! un autre tableau de réel double précision
double
precision
,dimension
(10,10)::tableau
! cette déclaration est équivalente à
double
precision
,dimension
(1:10,1:10)::tableau
On remarque que lorsqu'on donne la dimension d'une liste ou d'un tableau, on peut préciser les valeurs min et max des indices. Ceux-ci ne commencent pas forcément à 1 ou 0. Dans le troisième exemple on ne donne que la dimension, 10, l'indice commence alors à 1.
Dans une déclaration dynamique, on ne précise que le nombre d'indices souhaités. Puis, pendant l'exécution, on alloue, avec la commande allocate, la mémoire nécessaire au moment ou on a besoin de la variable. On peut ensuite libérer la zone mémoire lorsqu'on n'en a plus besoin, avec la commande deallocate.
! une liste d'entier
integer
,dimension
(:),allocatable
::liste
allocate
( liste( ndim ) )
....
deallocate
( liste(:) )
! un tableau de réel double précision
double
precision
,dimension
(:,:),allocatable
::tableau
allocate
( tableau( 1:ndim ,-ndim:ndim ) )
....
deallocate
( tableau(:,:) )
L'intérêt d'allouer les variables indicées de façon dynamique est de n'utiliser que la mémoire nécessaire au moment où on en a besoin. De plus, on peut calculer la dimension d'une variable indicée dans le programme et avoir une variable indicée de la dimension souhaitée.
Remarque : Dans les sous programmes la déclaration dynamique est impossible, sauf dans le cas des modules.
Dans le cas de la déclaration statique, l'utilisation des paramètres pour déclarer les dimensions des variables est utile.
On utilise la même syntaxe que pour une variable normale, sauf qu'il faut préciser le ou les indices.
! liste des premiers entiers impairs
liste(1) = 1
liste(2) = 3
liste(3) = 5
liste(4) = 7
! la matrice unité en dimension 2
M(1,1) = 1.d0 ; M(1,2) = 0.d0
M(1,1) = 0.d0 ; M(1,2) = 1.d0
En FORTRAN77, pour agir sur plusieurs éléments d'une variable indicée, il faut écrire une instruction pour chaque élément ou écrire une boucle. Le Fortran90 permet d'agir sur plusieurs éléments en une seule instruction.
integer
,parameter
::ndim=10
integer
,dimension
(1:ndim)::liste
double
precision
,dimension
(ndim,ndim)::matrice
! liste(:) se réfère à l'ensemble des éléments de liste
! matrice(:,:) se réfère à l'ensemble des éléments de matrice
! j'affecte 0 à tous les éléments de liste
liste(:) = 0
! j'affecte 0.d0 à tous les éléments de matrice
matrice(:,:) = 0.d0
! on met un 1.d0 dans la première ligne de matrice
matrice(1,:) = 1.d0
! on met un 2 dans les éléments de ndim/2 à ndim de liste
liste( ndim/2 : ndim ) = 2
Remarque : Il n'est pas nécessaire de préciser les : entre parenthèses, le nom de la variable est suffisant. Cependant par un souci de clarté et de lisibilité du programme il est préférable de les écrire.
Le Fortran 90 permet d'additionner et soustraire des variables indicées de même dimension sans utiliser de boucles. On utilise simplement les opérations standards comme pour une variable normale.
double
precision
,dimension
(3)::u,v,w,x
! somme de deux vecteurs
w(:) = u(:) + v(:)
! différence de deux vecteurs
w(:) = u(:) - v(:)
! ou encore
w(:) = 3.d0*u(:) - 0.5d0*v(:) + 2.d0*x(:)
La multiplication ou division de variables indicées ayant un sens particulier (produit scalaire, produit de matrice), des fonctions spéciales sont disponibles.
Remarque : Il n'est pas nécessaire de préciser les : entre parenthèses, le nom de la variable est suffisant. Cependant par un souci de clarté et de lisibilité du programme il est préférable de l'écrire.
On utilise la fonction sum(arg).
integer
,parameter
::ndim=10
double
precision
,dimension
(ndim)::liste
double
precision
,dimension
(ndim,ndim)::matrice
double
precision
::somme
somme = sum( liste(:) )
! normalisation de liste
liste(:) = liste(:) / sqrt
( sum( ( liste(:) )**2 ) )
somme = sum( matrice(:,:) )
On utilise la fonction product(arg).
integer
,parameter
::ndim=10
double
precision
,dimension
(ndim)::liste
double
precision
,dimension
(ndim,ndim)::matrice
double
precision
::produit
produit = product( liste(:) )
produit = product( matrice(:,:) )
On utilise la fonction transpose(arg).
integer
,parameter
::ndim=3
double
precision
,dimension
(ndim,ndim)::A,tA
tA(:,:) = transpose( A(:,:) )
On utilise la fonction matmult(arg1,arg2) qui permet de faire un produit de matrice. Il est cependant nécessaire que le premier indice soit celui de la ligne et le second celui de la colonne.
integer
,parameter
::ndim=3
double
precision
,dimension
(ndim,ndim)::A,B,P
double
precision
,dimension
(ndim)::X,Y
! Le produit de matrice A*B
P(:,:) = matmult( A(:,:) , B(:,:) )
! Matrice vecteur
Y(:) = matmult( A(:,:) , X(:) )
ATTENTION : Comme dans un produit de matrice, le nombre de colonnes du premier argument de matmult doit être égal au nombre de lignes du second argument.
On utilise la fonction dot_product(arg1,arg2), qui calcule le produit scalaire des vecteurs donnés en arguments 1 et 2.
integer
,parameter
::ndim=10
double
precision
,dimension
(ndim)::X,Y
double
precision
::scalaire
scalaire = dot_product( X(:) , Y(:) )