Avancée Fortran 90

Original: http://inside.mines.edu/~tkaiser/fortran/


Timothy H. Kaiser,Ph.D.
Organisation informatique d’énergie dorée
http://Inside.mines.edu/~tkaiser/Fortran/F90.html
Rédigés : Été 1997
Introduction
  • Introduction personnelle
  • L’esprit des auteurs de langue
  • Justification des thèmes abordés
  • Classification des thèmes abordés
  • Liste des sujets couverts
  • Format de notre conversation
  • Viande
Qui suis je ?
  • Fond large expérience
    • Physique
    • Génie électrique
    • Informatique
  • . gt de 25 ans de programmation.
    • Industrie de défense
    • Milieu universitaire
  • Langages
    • Fortran
    • C
    • C++
    • Pascal
    • Lisp
    • Java
    • Python
    • D’autres
  • Bêtatesteur de plusieurs compilateurs Fortran
  • J’ai eu la chance de faire à peu près chaque erreur dans le livre, et certains qui n’est pas

L’esprit des auteurs de langue

Que pensaient-ils ?
  • Activer les codes portables
    • Même précision
    • Inclure les nombreuses extensions courantes
  • Programmes plus fiables
  • S’éloigner le matériel sous-jacent
  • Déplacer vers la programmation parallèle
  • Exécuter des anciens programmes
  • Facilité de programmation
    • Écriture
    • Maintien
    • Compréhension
    • Lecture
  • Récupérer les utilisateurs C et C++

Pourquoi Fortran ?

“Je ne sais pas ce que les caractéristiques techniques des
le langage standard pour les scientifiques et d’ingénierie
calcul en l’an 2000 sera… mais je sais qu’il
s’appellera Fortran. » John Backus
  • Langue de choix pour la programmation scientifique
  • Base importante d’utilisateurs installés.
  • Fortran 90 a la plupart des fonctionnalités de C et puis certains
  • Langue principale sur le supercalculateur de SP d’IBM et de toutes les machines Cray
  • Les compilateurs produisent de meilleurs programmes

Justification des sujets

  • Améliorer les performances
  • Portabilité
  • Améliorer la fiabilité
  • Améliorer la maintenabilité

Classement des sujets

  • Nouvelles fonctionnalités utiles
  • Vieux trucs
  • Caractéristiques de puissance

Liste des thèmes abordés

  1. Liste des thèmes abordés
  2. Format pour notre conversation
  3. Ce qui est un algorithme génétique
  4. Algorithme simple pour un GA
  5. Notre problème d’exemple
  6. Début de la vraie discussion Fortran 90
  7. En comparant une routine FORTRAN 77 à une routine Fortran 90
  8. Fonctionnalités obsolètes
  9. Nouvelle source de forme (et des choses connexes)
  10. Nouvelle méthode de déclaration des données
  11. Installation d’aimable
  12. Modules
  13. Sous-routines et des fonctions du module
  14. Tableaux à répartir (les bases)
  15. Passage de tableaux à sous-routines
  16. Interface pour le passage de tableaux
  17. Intention et des arguments facultatifs
  18. Types de données dérivés
  19. L’utilisation de types définis
  20. Opérateurs définis par l’utilisateur
  21. Introduction de fonctions récursives
  22. Fonctions récursives Fortran 90
  23. Pointeurs
  24. Fonction et la surcharge de la sous-routine
  25. Routines Fortran Minval et Minloc
  26. Affectation de pointeur
  27. Plus de son utilisation de pointeur, d’association et d’annuler
  28. Utilisation de pointeur pour faire référence à un tableau
  29. Cession de données avec les structures
  30. À l’aide de l’opérateur défini utilisateur
  31. Passage de tableaux avec une basse donnée arbitraire limites
  32. Utilisant des pointeurs pour accéder aux sections de tableaux
  33. Allocation d’un tableau à l’intérieur d’une sous-routine
  34. Notre fonction de remise en forme
  35. Listes chaînées
  36. Utilisation de la liste chaînée
  37. Notre représentation de la carte
  38. E/s de caractère et de progresser non
  39. Fonctions de date et d’heure
  40. E/s internes
  41. S’enquérir de fonction
  42. NameList
  43. Fonctions vectorielles d’une valeur
  44. Source complète pour les discussions récentes
  45. Certaines fonctions intrinsèques spécifique de tableau
  46. Le reste de notre GA
  47. Informations de compilateur
  48. Fortan 95
  49. Résumé
  50. Références

Format pour notre conversation

  • Nous allons « développer » une application
    • F90 et équipant
    • Afficher le code source
    • Expliquer quoi et pourquoi comme nous le faisons
    • Des parties importantes du code source sont en rouge (si je ne parle pas à ce sujet, renseignez-vous!)
  • Application est un algorithme génétique
    • Facile à comprendre et programmer
    • Offre des opportunités intéressantes pour l’amélioration

Ce qui est un algorithme génétique

  • Un système de « suboptimization »
    • Trouver des solutions aux problèmes difficiles bonnes, mais peut-être pas optimales,
    • Souvent utilisé sur NP-difficile ou des problèmes d’optimisation combinatoire
  • Exigences
    • Solution (s) du problème représenté par une chaîne
    • Une fonction de remise en forme
      • Prend en entrée la chaîne solution
      • Sortie le bien-fondé de la solution
    • Une méthode de combiner les chaînes de la solution pour générer de nouvelles solutions
Trouver des solutions aux problèmes de l’évolution darwinienne
Ar de solutions possibles si des comme des entités vivantes dans une population
Les cordes sont les codes génétiques pour les personnes
Des individus plus aptes sont autorisés à survivre pour reproduire

Algorithme simple pour un GA

  • Générer une population initiale, une collection de chaînes
  • faire pendant un certain temps
    • évaluer chaque individu (string) de la population à l’aide de la fonction de remise en forme
    • trier la population avec plus aptes à venir vers le haut
    • autoriser les personnes plus aptes à reproduire « sexuel » remplaçant l’ancienne population
    • permettre de mutation
  • fin

Notre problème d’exemple

  • Instance
    • Donné une carte du pays, les États de N et un nombre fixe de couleurs
    • Trouver un coloriage de la carte, si elle existe, tel qu’aucuns deux États qui partagent une frontière n’ont la même couleur
  • Notes
    • En général, pour un nombre fixe de couleurs et une carte arbitraire, la seule façon connue de trouver si il y a une coloration valide est une force brute de recherche avec le nombre de combinaisons = (NUMBER_OF_COLORS)**(NSTATES)
    • Les chaînes de notre population sont vecteurs entiers représentent la coloration
    • Notre fonction de remise en forme retourne le nombre de violations de la frontière
    • Les recherches de GA pour un mappage avec quelques, j’espère que les violations 0
    • Ce problème est lié à plusieurs problèmes importants de NP_HARD en informatique
      • Ordonnancement du processeur
      • Communication et grille d’allocation pour le parallélisme
      • Routage

Début de la vraie discussion Fortran 90

Un aperçu : en comparant une routine FORTRAN 77 à une routine Fortran 90

  • La routine est l’un des générateurs de nombres aléatoires de : Numerical Recipes, The Art of Scientific Computing. Presse, Teukolsky, Vetterling et Flannery. Cambridge University Press, 1986.
  • Changements
    • bogues corrects
    • accroître la fonctionnalité
    • portabilité de l’aide
    function ran1(idum)
        real ran1
        integer idum
        real r(97)
        parameter ( m1=259200,ia1=7141,ic1=54773)
        parameter ( m2=134456,ia2=8121,ic2=28411)
        parameter ( m3=243000,ia3=4561,ic3=51349)
        integer j
        integer iff,ix1,ix2,ix3
        data iff /0/
        if (idum<0.or.iff.eq.0)then
            rm1=1.0/m1
            rm2=1.0/m2
            iff=1
            ix1=mod(ic1-idum,m1)
            ix1=mod(ia1*ix1+ic1,m1)
            ix2=mod(ix1,m2)
            ix1=mod(ia1*ix1+ic1,m1)
            ix3=mod(ix1,m3)
            do 11 j=1,97
                ix1=mod(ia1*ix1+ic1,m1)
                ix2=mod(ia2*ix2+ic2,m2)
                r(j)=(real(ix1)+real(ix2)*rm2)*rm1
 11           continue
            idum=1
        endif
        ix1=mod(ia1*ix1+ic1,m1)
        ix2=mod(ia2*ix2+ic2,m2)
        ix3=mod(ia3*ix3+ic3,m3)
        j=1+(97*ix3)/m3
        if(j>97.or.j<1)then
            write(*,*)' error in ran1 j=',j
            stop
        endif
        ran1=r(j)
        r(j)=(real(ix1)+real(ix2)*rm2)*rm1
        return
     end
module ran_mod 
contains 
     function ran1(idum)
        use numz
        implicit none  !note after use statement
        real(b8) ran1
        integer, intent(inout), optional :: idum
        real(b8) r(97),rm1,rm2
        integer, parameter :: m1=259200,ia1=7141,ic1=54773
        integer, parameter :: m2=134456,ia2=8121,ic2=28411
        integer, parameter :: m3=243000,ia3=4561,ic3=51349
        integer j
        integer iff,ix1,ix2,ix3
        data iff /0/
        save ! corrects a bug in the original routine
        if(present(idum))then
          if (idum<0.or.iff.eq.0)then
            rm1=1.0_b8/m1
            rm2=1.0_b8/m2
            iff=1
            ix1=mod(ic1-idum,m1)
            ix1=mod(ia1*ix1+ic1,m1)
            ix2=mod(ix1,m2)
            ix1=mod(ia1*ix1+ic1,m1)
            ix3=mod(ix1,m3)
            do j=1,97
                ix1=mod(ia1*ix1+ic1,m1)
                ix2=mod(ia2*ix2+ic2,m2)
                r(j)=(real(ix1,b8)+real(ix2,b8)*rm2)*rm1
            enddo
            idum=1
          endif
        endif
        ix1=mod(ia1*ix1+ic1,m1)
        ix2=mod(ia2*ix2+ic2,m2)
        ix3=mod(ia3*ix3+ic3,m3)
        j=1+(97*ix3)/m3
        if(j>97.or.j<1)then
            write(*,*)' error in ran1 j=',j
            stop
        endif
        ran1=r(j)
        r(j)=(real(ix1,b8)+real(ix2,b8)*rm2)*rm1
        return
     end function ran1
Fonctionnalités obsolètes
  • Les suivants sont disponibles en Fortran 90. En revanche, le concept « obsolescence » est introduit. Cela signifie que certaines constructions peuvent être enlevées à l’avenir.
  • Arithmétique-instruction IF
  • Variables de contrôle dans une boucle qui flottent point ou virgule flottante double précision
  • Clôturant les boucles plusieurs sur la même instruction
  • Clôturant la boucle d’une autre manière qu’ou faire de la fin
  • Autre retour
  • Allez ensuite un bloc externe END IF
  • PAUSE
  • ASSIGNER et GOTO et FORMAT, c’est l’ensemble du concept « déclaration numéro variable ».
  • Hollerith en FORMAT d’édition.

Nouvelle forme de la source (et choses connexes)

  • Résumé
  • ! maintenant indique le début d’un commentaire
  • & indique la ligne suivante est une continuation
  • Les lignes peuvent être plus de 72 caractères
  • Déclarations peuvent commencer dans n’importe quelle colonne
  • Utilisation ; mettre plusieurs instructions sur une seule ligne
  • Nouvelles formes pour le faire en boucle
  • Beaucoup de fonctions est génériques
  • 32 noms de personnages
  • Bon nombre de nouvelles techniques d’attribution de tableau
  • Caractéristiques
    • Flexibilité peut aider à la lisibilité du programme
    • Lisibilité diminue les erreurs
  • Ya eu !
    • Ne peuvent plus utiliser C pour commencer un commentaire
    • Caractères dans la colonne 5 est n’est plus continuer
    • Onglet n’est pas un caractère valide (peut produire un avertissement)
    • Caractères passé 72 maintenant comte
!23456789
program darwin
     real a(10), b(10), c(10), d(10), e(10), x, y
     integer odd(5),even(5)
     write(*,*)"starting ",&  ! this line is continued by using "&"
               "darwin"       ! this line in a continued from above
     x=1; y=2; write(*,*)x,y  ! multiple statement per line -- rarely a good idea
     do i=1,10    ! statement lable is not required for do
        e(i)=i
     enddo
     odd= (/ 1,3,5,7,9 /)  ! array assignment
     even=(/ 2,4,6,8,10 /) ! array assignment
     a=1          ! array assignment, every element of a = 1
     b=2
     c=a+b+e      ! element by element assignment
     c(odd)=c(even)-1  ! can use arrays of indices on both sides
     d=sin(c)     ! element by element application of intrinsics
     write(*,*)d
     write(*,*)abs(d)  ! many intrinsic functions are generic
 a_do_loop : do i=1,10
               write(*,*)i,c(i),d(i)
             enddo a_do_loop
     do
        if(c(10) < 0.0 ) exit
        c(10)=c(10)-1
     enddo
     write(*,*)c(10)
     do while (c(9) > 0)
        c(9)=c(9)-1
     enddo
     write(*,*)c(9)
end program

Nouvelle méthode de déclaration des données

  • Motivation
    • Les variables peuvent avoir des attributs tels que maintenant
      • Paramètre
      • Enregistrer
      • Dimension
    • Attributs sont assignés dans l’instruction de déclaration de variable
  • Une variable peut avoir plusieurs attributs
  • Nécessite Fortran 90 d’avoir un nouveau formulaire de déclaration
 
    integer, parameter :: in2 = 14
    real, parameter :: pi = 3.141592653589793239
    real, save, dimension(10) :: cpu_times,wall_times
!****    the old way of doing the same    ****!
!****    real cpu_times(10),wall_times(10) ****!
!****    save cpu_times, wall_times        ****!
  • Autres attributs
  • à répartir
  • public
  • privé
  • cible
  • pointeur
  • intention
  • en option

Installation d’aimable

  • Motivation
    • Supposons que nous avons un programme que nous voulons exécuter sur deux machines différentes
      • Nous voulons la même représentation des nombres réels sur les deux machines (même nombre de chiffres significatifs)
      • Problème : différentes machines ont des représentations différentes pour reals

Chiffres de précision pour le type de machine et des données

Machine/Data Type     Real       Double Precision
IBM (SP)       6           15
Cray (T90)     15           33
Cray (T3E)     15           15

********* ou*********

  • Nous pourrions vouloir courir avec au moins 6 chiffres aujourd’hui et au moins 14 chiffres demain
  • Utilisez la fonction Select_Real_Kind(P) pour créer un type de données avec précision de chiffres P

sp001 % cat darwin.f
program darwin
! e has at least 4 significant digits
  real(selected_real_kind(4))e
! b8 will be used to define reals with 14 digits
  integer, parameter:: b8 = selected_real_kind(14)
  real(b8), parameter :: pi = 3.141592653589793239_b8 ! note usage of _b8
                                                      ! with  a constant
                                                      ! to force precision
 e= 2.71828182845904523536
  write(*,*)”starting “,&  ! this line is continued by using “&”
            “darwin”       ! this line in a continuation from above
  write(*,*)”pi has “,precision(pi),” digits precision “,pi
  write(*,*)”e has   “,precision(e),” digits precision “,e
end program

  % darwin
 starting darwin
 pi has  15  digits precision  3.14159265358979312
 e has    6  digits precision  2.718281746

sp001 %

 

  • Permet de convertir de/compte tenu de la précision pour toutes les variables créées à l’aide de « b8 » en changeant la définition de « b8 »
  • Utilisez la fonction Select_Real_Kind(P,R) pour créer un type de données contenant des chiffres de précision et de la gamme exposant de R P

Modules

  • Motivation :
  • Utilisation courante de bloc est sujette à erreur
  • Apporter le plus de capacité de blocs communs mais plus sûrs
  • Fournir des possibilités au-delà des blocs communs
  • Peuvent contenir des modules :
  • Définitions de données
  • Données soient partagent très semblable à l’aide d’un commun étiqueté
  • Fonctions et sous-routines
  • Interfaces (plus sur cela plus tard)
  • Vous « inclure » un module avec une instruction « use »

module numz
  integer, parameter:: b8 = selected_real_kind(14)
  real(b8), parameter :: pi = 3.141592653589793239_b8
  integer gene_size
end module

program darwin
  use numz
  implicit none   ! now part of the standard, put it after the use statements
  write(*,*)"pi has ",precision(pi)," digits precision ",pi
  call set_size()
  write(*,*)"gene_size=",gene_size
end program

subroutine set_size
  use numz
  gene_size=10
end subroutine set_size
 pi has  15  digits precision  3.14159265358979312
 gene_size= 10

 


Sous-routines et des fonctions du module

  • Motivation :
    • Encapsuler des sous-routines et des fonctions connexes
    • « UTILISATION » de ces fonctions dans un programme ou sous-programme
    • Peut être fourni en tant que bibliothèque
    • Seulement les routines qui contient l’instruction use peuvent voir les routines
  • Exemple est un paquet de numéro aléatoire :

module ran_mod
! module contains three functions
! ran1 returns a uniform random number between 0-1
! spread returns random number between min - max
! normal returns a normal distribution

contains
    function ran1()  !returns random number between 0 - 1
        use numz
        implicit none
        real(b8) ran1,x
        call random_number(x) ! built in fortran 90 random number function
        ran1=x
    end function ran1

    function spread(min,max)  !returns random number between min - max
        use numz
        implicit none
        real(b8) spread
        real(b8) min,max
        spread=(max - min) * ran1() + min
    end function spread

    function normal(mean,sigma) !returns a normal distribution
        use numz
        implicit none
        real(b8) normal,tmp
        real(b8) mean,sigma
        integer flag
        real(b8) fac,gsave,rsq,r1,r2
        save flag,gsave
        data flag /0/
        if (flag.eq.0) then
        rsq=2.0_b8
            do while(rsq.ge.1.0_b8.or.rsq.eq.0.0_b8) ! new from for do
                r1=2.0_b8*ran1()-1.0_b8
                r2=2.0_b8*ran1()-1.0_b8
                rsq=r1*r1+r2*r2
            enddo
            fac=sqrt(-2.0_b8*log(rsq)/rsq)
            gsave=r1*fac
            tmp=r2*fac
            flag=1
        else
            tmp=gsave
            flag=0
        endif
        normal=tmp*sigma+mean
        return
    end function normal

end module ran_mod


Exersize 1: Écrire un programme qui renvoie 10 nombres aléatoires uniformes.


Tableaux à répartir (les bases)

  • Motivation :
    • Au moment de la compilation nous ne saurons pas la taille un tableau doivent être
    • On peut vouloir changer la taille du problème sans recompiler
    • Tableaux allouable permettent de définir la taille en cours d’exécution
    • Nous définissons la taille du tableau à l’aide de l’instruction allocate
    • On peut vouloir changer la limite inférieure d’un tableau
  • Un exemple simple :
module numz
  integer, parameter:: b8 = selected_real_kind(14)
  integer gene_size,num_genes
  integer,allocatable :: a_gene(:),many_genes(:,:)
end moduleprogram darwin
    use numz
    implicit none
    integer ierr
    call set_size()
    allocate(a_gene(gene_size),stat=ierr) !stat= allows for an error code return
    if(ierr /= 0)write(*,*)"allocation error"  ! /= is .ne.
    allocate(many_genes(gene_size,num_genes),stat=ierr)  !2d array
    if(ierr /= 0)write(*,*)"allocation error"
    write(*,*)lbound(a_gene),ubound(a_gene) ! get lower and upper bound
                                            ! for the array
    write(*,*)size(many_genes),size(many_genes,1) !get total size and size
                                                  !along 1st dimension
    deallocate(many_genes) ! free the space for the array and matrix
    deallocate(a_gene)
    allocate(a_gene(0:gene_size)) ! now allocate starting at 0 instead of 1
    write(*,*)allocated(many_genes),allocated(a_gene) ! shows if allocated
    write(*,*)lbound(a_gene),ubound(a_gene)
end program
 subroutine set_size
    use numz
    write(*,*)'enter gene size:'
    read(*,*)gene_size
    write(*,*)'enter number of genes:'
    read(*,*)num_genes
end subroutine set_size
   enter gene size:
10
 enter number of genes:
20
           1          10
         200          10
 F T
           0          10
 


Passage de tableaux à sous-routines

  • Il existe plusieurs façons de spécifier des tableaux pour les sous-routines
    • Forme explicite
    • entier, dimension (8,8):: an_explicit_shape_array
    • Taille supposée
    • entier, dimension(i,*)::an_assumed_size_array
    • Forme hypothétique
    • entier, dimension(:,:)::an_assumed_shape_array
  • Exemple

subroutine arrays(an_explicit_shape_array,&
                  i                      ,& !note we pass all bounds except the last
                  an_assumed_size_array  ,&
                  an_assumed_shape_array)
! Explicit shape
    integer, dimension(8,8)::an_explicit_shape_array
! Assumed size
    integer, dimension(i,*)::an_assumed_size_array
! Assumed Shape
    integer, dimension(:,:)::an_assumed_shape_array
    write(*,*)sum(an_explicit_shape_array)
    write(*,*)lbound(an_assumed_size_array) ! why does sum not work here?
    write(*,*)sum(an_assumed_shape_array)
end subroutine

Interface pour le passage de tableaux
  • Mise en garde!! Lors du passage de tableaux forme supposée comme arguments, vous devez fournir une interface
    • Similaires aux prototypes C mais beaucoup plus polyvalent
    • L’interface est une copie de la ligne de l’invocation et la définition de l’argument
    • Les modules sont un bon endroit pour les interfaces
    • Si une procédure fait partie d’une section « contient » dans un module, une interface n’est pas nécessaire
  • !!!! AVERTISSEMENT!!! Le compilateur ne peut pas vous dire que vous avez besoin d’une interface

module numz
    integer, parameter:: b8 = selected_real_kind(14)
    integer,allocatable :: a_gene(:),many_genes(:,:)
end module

module face
    interface fitness
        function fitness(vector)
        use numz
        implicit none
        real(b8) fitness
        integer, dimension(:) ::  vector
        end function fitness
    end interface
end module

program darwin
    use numz
    use face
    implicit none
    integer i
    integer vect(10) ! just a regular array
    allocate(a_gene(10));allocate(many_genes(3,10))
    a_gene=1  !sets every element of a_gene to 1
    write(*,*)fitness(a_gene)
    vect=8
    write(*,*)fitness(vect) ! also works with regular arrays
    many_genes=3  !sets every element to 3
    many_genes(1,:)=a_gene  !sets column 1 to a_gene
    many_genes(2,:)=2*many_genes(1,:)
    do i=1,3
        write(*,*)fitness(many_genes(i,:))
    enddo
    write(*,*)fitness(many_genes(:,1))  !go along other dimension
!!!!write(*,*)fitness(many_genes)!!!!does not work
end program

function fitness(vector)
    use numz
    implicit none
    real(b8) fitness
    integer, dimension(:)::  vector ! must match interface
    fitness=sum(vector)
end function


Exersize 2: Exécuter ce programme en utilisant le « ne fonctionne pas ligne ». Pourquoi ? À l’aide de fonctions intrinsèques make ça marche ?

Exersize 3: Prouver que f90 ne « passe pas par adresse ».

Intention et des arguments facultatifs

  • Motivation :
    • Nous pouvons avoir une fonction ou une sous-routine qui nous pourrions vouloir pas toujours passer par tous les arguments
    • Initialisation
  • Deux exemples

Le générateur de nombres aléatoire intrinsèque de l’ensemencement requiert des arguments de mot clé

  • Pour définir un argument facultatif dans notre propre fonction, nous utilisons l’attribut facultatif
    integer :: my_seed
        becomes
  integer, optional :: my_seedmodule ran_mod
! ran1 returns a uniform random number between 0-1
! the seed is optional and used to reset the generator
contains
   function ran1(my_seed)
      use numz
      implicit none
      real(b8) ran1,r
      integer, optional ,intent(in) :: my_seed  ! optional argument not changed in the routine
      integer,allocatable :: seed(:)
      integer the_size,j
      if(present(my_seed))then            ! use the seed if present
          call random_seed(size=the_size) ! how big is the intrisic seed?
          allocate(seed(the_size))        ! allocate space for seed
          do j=1,the_size                 ! create the seed
             seed(j)=abs(my_seed)+(j-1)   ! abs is generic
          enddo
          call random_seed(put=seed)      ! assign the seed
          deallocate(seed)                ! deallocate space
      endif
      call random_number(r)
      ran1=r
  end function ran1
end moduleprogram darwin
    use numz
    use ran_mod          ! interface required if we have
                         ! optional or intent arguments
    real(b8) x,y
    x=ran1(my_seed=12345) ! we can specify the name of the argument
    y=ran1()
    write(*,*)x,y
    x=ran1(12345)         ! with only one optional argument we don't need to
    y=ran1()
    write(*,*)x,y
end program

  • Intention est une allusion au compilateur pour activer l’optimisation
  • Intent(in)
    • Nous ne changerons pas cette valeur dans notre sous-routine
  • Intent(out)
    • Nous allons définir cette valeur dans notre routine
  • Intent(inout)
    • La situation normale

Types de données dérivés

  • Motivation :
    • Types de données dérivés permet de regrouper différents types de données (entiers, réels, personnage complexe)
    • Ne peut pas être fait en F77, bien que les gens ont « truquées » il
  • Exemple
    • Dans notre GA, nous définissons une collection de gènes comme un 2d array
    • Nous appelons la fonction de remise en forme pour chaque membre de la collection
    • Nous voulons trier la collection de gènes basée sur le résultat de la fonction de remise en forme
    • Définir un type de données qui contient la valeur de remise en forme ainsi qu’un index dans le tableau 2d
      • Créer un tableau de ce type de données, 1 pour chaque membre de la collection
      • Appeler la fonction de remise en forme avec le résultat étant placé dans le nouveau type de données ainsi qu’un pointeur dans le tableau
  • Encore une fois les modules sont un bon endroit pour les définitions de type de données

module galapagos
    use numz
    type thefit !the name of the type
      sequence  ! sequence forces the data elements
                ! to be next to each other in memory
                ! where might this be useful?
      real(b8) val   ! our result from the fitness function
      integer index  ! the index into our collection of genes
    end type thefit
end module


L’utilisation de types définis

  • Utiliser le % de référencer les différents composants du type de données dérivé
program darwin
    use numz
    use galapagos ! the module that contains the type definition
    use face      ! contains various interfaces
 implicit none
! define an allocatable array of the data type
! than contains an index and a real value
    type (thefit),allocatable ,target :: results(:)
! create a single instance of the data type
    type (thefit) best
    integer,allocatable :: genes(:,:) ! our genes for the genetic algorithm
    integer j
    integer num_genes,gene_size
    num_genes=10
    gene_size=10
    allocate(results(num_genes))         ! allocate the data type
                                         ! to hold fitness and index
    allocate(genes(num_genes,gene_size)) ! allocate our collection of genes
    call init_genes(genes)               ! starting data
    write(*,'("input")') ! we can put format in write statement
    do j=1,num_genes
       results(j)%index=j
       results(j)%val=fitness(genes(j,:)) ! just a dummy routine for now
       write(*,"(f10.8,i4)")results(j)%val,results(j)%index
    enddo
end program

Opérateurs définis par l’utilisateur

  • Motivation
  • Avec les types de données dérivés nous pourrions vouloir (nécessité) définir des opérations
  • (Affectation est prédéfinie)
  • Exemple :
    • <, >, ne == pas défini pour nos types de données
      • Nous voulons trouver le minimum de nos valeurs de remise en forme, donc nous devons < opérateur
      • Dans notre routine de sorte que nous voulons faire <, > ==
      • En termes de C++, les opérateurs sont surchargés
    • Nous sommes libres de définir de nouveaux opérateurs
  • Processus en deux étapes pour définir des opérateurs
    • Définissez une interface spéciale
    • Définir la fonction qui effectue l’opération
module sort_mod
!defining the interfaces
  interface operator (.lt.)  ! overloads standard .lt.
    module procedure theless ! the function that does it
  end interface  interface operator (.gt.)   ! overloads standard .gt.
    module procedure thegreat ! the function that does it
  end interface  interface operator (.ge.)  ! overloads standard .ge.
    module procedure thetest ! the function that does it
  end interface  interface operator (.converged.)  ! new operator
    module procedure index_test     ! the function that does it
  end interface

contains      ! our module will contain
              ! the required functions
 

  function theless(a,b) ! overloads < for the type (thefit)
    use galapagos
    implicit none
    type(thefit), intent (in) :: a,b
    logical theless           ! what we return
    if(a%val < b%val)then     ! this is where we do the test
        theless=.true.
    else
        theless=.false.
    endif
    return
  end function theless

  function thegreat(a,b) ! overloads > for the type (thefit)
    use galapagos
    implicit none
    type(thefit), intent (in) :: a,b
    logical thegreat
    if(a%val > b%val)then
        thegreat=.true.
    else
        thegreat=.false.
    endif
    return
  end function thegreat
 

function thetest(a,b)   ! overloads >= for the type (thefit)
    use galapagos
    implicit none
    type(thefit), intent (in) :: a,b
    logical thetest
    if(a%val >= b%val)then
        thetest=.true.
    else
        thetest=.false.
    endif
    return
end function thetest
function index_test(a,b) ! defines a new operation for the type (thefit)
    use galapagos
    implicit none
    type(thefit), intent (in) :: a,b
    logical index_test
    if(a%index > b%index)then   ! check the index value for a difference
        index_test=.true.
    else
        index_test=.false.
    endif
    return
end function index_test


Introduction de fonctions récursives

  • Notes
  • Fonction récursive est celui qui s’appelle
  • Tout ce qui peut être fait avec un do boucle peut se faire à l’aide d’une fonction récursive
  • Motivation
  • Il est parfois plus facile de penser de manière récursive
  • Diviser une conquer algorithmes sont récursifs par nature
    • Rapide FFT
    • La recherche
    • Tri

Algorithme de recherche d’au moins un tableau

    function findmin(array)
        is size of array 1?
           min in the array is first element
        else
           find minimum in left half of array using findmin function
           find minimum in right half of array using findmin function
           global minimum is min of left and right half
    end function

Fonctions récursives Fortran 90

  • Les fonctions récursives devraient avoir une interface
  • Les mots clés résultat et récursives sont exigés dans le cadre de la définition de fonction
  • Exemple est qu’une fonction détecte que la valeur minimale pour un tableau
recursive function realmin(ain) result (themin)
! recursive and result are required for recursive functions
    use numz
    implicit none
    real(b8) themin,t1,t2
    integer n,right
    real(b8) ,dimension(:) :: ain
    n=size(ain)
    if(n == 1)then
       themin=ain(1) ! if the size is 1 return value
    return
    else
      right=n/2
      t1=realmin(ain(1:right))   ! find min in left half
      t2=realmin(ain(right+1:n)) ! find min in right half
      themin=min(t1,t2)          ! find min of the two sides
     endif
end function
  • Exemple 2, c’est que le même, sauf les données d’entrée est notre type de données dérivé
!this routine works with the data structure thefit not reals
recursive function typemin(ain) result (themin)
    use numz
 use sort_mod
 use galapagos
 implicit none
 real(b8) themin,t1,t2
 integer n,right
    type (thefit) ,dimension(:) :: ain ! this line is different
 n=size(ain)
 if(n == 1)then
     themin=ain(1)%val  ! this line is different
  return
 else
  right=n/2
  t1=typemin(ain(1:right))
  t2=typemin(ain(right+1:n))
  themin=min(t1,t2)
 endif
end function

Pointeurs

  • Motivation
  • Pouvez augmenter les performances
  • Peut améliorer la lisibilité
  • Requis pour certains types de données dérivés (les listes chaînées et les arbres)
  • Utile pour l’attribution des « tableaux » au sein de sous-routines
  • Utile pour le référencement des sections de tableaux
  • Notes
  • Pointeurs peuvent être considérées comme un alias à une autre variable
  • Dans certains cas peuvent être utilisés à la place d’un tableau
  • Pour affecter un pointeur utilisation => au lieu de juste =
  • Contrairement à C et C++, arithmétique de pointeur n’est pas autorisé
  • Premier exemple de pointeur
  • Analogue à la routine de findmin dernier
  • Renvoyer un pointeur vers le minimum
recursive function pntmin(ain) result (themin) ! return a pointer
 use numz
 use galapagos
 use sort_mod ! contains the < operator for thefit type
 implicit none
 type (thefit),pointer:: themin,t1,t2
 integer n,right
    type (thefit) ,dimension(:),target :: ain
 n=size(ain)
 if(n == 1)then
     themin=>ain(1) !this is how we do pointer assignment
  return
 else
  right=n/2
  t1=>pntmin(ain(1:right))
  t2=>pntmin(ain(right+1:n))
  if(t1 < t2)then; themin=>t1; else; themin=>t2; endif
 endif
end function

Exercice 4: Écrire soigneusement un récursif N ! programme.


Fonction et la surcharge de la sous-routine

  • Motivation
  • Nous permet d’appeler des fonctions ou une sous-routine portant le même nom avec les types d’arguments différents
  • Augmente la lisibilité
  • Notes :
  • Un concept similaire à la surcharge d’opérateur
  • Nécessite une interface
  • Syntaxe des sous-routines est même en ce qui concerne les fonctions
  • Nombreuses fonctions intrinsèques ont cette capacité
    • ABS (entier complexe, de nombres réels)
    • Sin, cos, tan, exp (nombres réels, complexes)
    • fonctions de tableau (entier complexe, de nombres réels)
  • Exemple
  • Rappelons que nous avons eu deux fonctions qui fait la même chose mais avec les types d’arguments différents
        recursive function realmin(ain) result (themin)
        real(b8) ,dimension(:) :: ain        recursive function typemin(ain) result (themin)
        type (thefit) ,dimension(:) :: ain

  • Nous pouvons définir une interface générique pour ces deux fonctions et les appeler à l’aide du même nom

! note we have two functions within the same interface
! this is how we indicate function overloading
! both functions are called "findmin" in the main program
interface findmin

!
! the first is called with an array of reals as input
        recursive function realmin(ain) result (themin)
          use numz
       real(b8) themin
          real(b8) ,dimension(:) :: ain
        end function

! the second is called with a array of data structures as input
     recursive function typemin(ain) result (themin)
          use numz
    use galapagos
       real(b8) themin
          type (thefit) ,dimension(:) :: ain
     end function
    end interface

  • Exemple d’utilisation
program darwin
    use numz
    use ran_mod
    use galapagos ! the module that contains the type definition
    use face      ! contains various interfaces
    use sort_mod  ! more about this later it
                  ! contains our sorting routine
      ! and a few other tricks
    implicit none
! create an allocatable array of the data type
! than contains an index and a real value
    type (thefit),allocatable ,target :: results(:)
! create a single instance of the data type
    type (thefit) best
! pointers to our type
    type (thefit) ,pointer :: worst,tmp
    integer,allocatable :: genes(:,:) ! our genes for the ga
    integer j
    integer num_genes,gene_size
    real(b8) x
    real(b8),allocatable :: z(:)
    real(b8),pointer :: xyz(:) ! we'll talk about this next
    num_genes=10
    gene_size=10
    allocate(results(num_genes))         ! allocate the data type to
    allocate(genes(num_genes,gene_size)) ! hold our collection of genes
    call init_genes(genes)               ! starting data
    write(*,'("input")')
    do j=1,num_genes
       results(j)%index=j
       results(j)%val=fitness(genes(j,:)) ! just a dummy routine
       write(*,"(f10.8,i4)")results(j)%val,results(j)%index
    enddo    allocate(z(size(results)))
    z=results(:)%val ! copy our results to a real array! use a recursive subroutine operating on the real array
    write(*,*)"the lowest fitness: ",findmin(z)
! use a recursive subroutine operating on the data structure
    write(*,*)"the lowest fitness: ",findmin(results)

Routines Fortran Minval et Minloc
  • Fortran a des routines pour trouver les valeurs minimale et maximale dans les baies et les emplacements
    • minVal
    • MaxVal
    • minloc (renvoie un tableau)
    • maxloc (renvoie un tableau)
! we show two other methods of getting the minimum fitness
! use the built in f90 routines on a real array
    write(*,*)"the lowest fitness: ",minval(z),minloc(z)

Affectation de pointeur

  • Voilà comment nous les utilisons la pointeur fonction définie ci-dessus
  • pire est un pointeur vers notre type de données
  • Notez l’utilisation de =>
! use a recursive subroutine operating on the data
! structure and returning a pointer to the result
    worst=>pntmin(results) ! note pointer assignment
! what will this line write?
 write(*,*)"the lowest fitness: ",worst

Plus de son utilisation de pointeur, d’association et d’annuler

  • Motivation
  • Besoin de trouver si les pointeurs pointent vers rien
  • Besoin de trouver si deux pointeurs pointent vers la même chose
  • Besoin de libérer et d’annuler quand ils ne sont plus utilisés
  • Utilisation
  • Nous pouvons utiliser associated() pour dire si un pointeur a été mis
  • Nous pouvons utiliser associated() pour comparer des pointeurs
  • Nous utilisation annulent à zéro un pointeur
! This code will print "true" when we find a match,
! that is the pointers point to the same object
    do j=1,num_genes
     tmp=>results(j)
        write(*,"(f10.8,i4,l3)")results(j)%val,   &
                                results(j)%index, &
           associated(tmp,worst)
    enddo
    nullify(tmp)
  • Notes :
  • Si un pointeur est réduit à néant l’objet auquel elle points n’est pas libéré.
  • En général, pointeurs, mais aussi des tableaux allouable devient indéfinies en quittant une sous-routine
  • Cela peut provoquer une fuite de mémoire

Utilisation de pointeur pour référencer un tableau sans copier

  • Motivation
  • Notre routine de tri appelle un récursif de routine de tri
  • C’est salissant et inefficace pour passer le tableau à la routine récursive
  • Solution
  • Nous définissons un pointeur « global » dans un module
  • Nous pointer le pointeur vers notre tableau d’entrée
module Merge_mod_types
    use galapagos
    type(thefit),allocatable :: work(:) ! a "global" work array
    type(thefit), pointer:: a_pntr(:)   ! this will be the pointer to our input array
end module Merge_mod_types
 subroutine Sort(ain, n)
    use Merge_mod_types
    implicit none
    integer n
    type(thefit), target:: ain(n)
    allocate(work(n))
    nullify(a_pntr)
    a_pntr=>ain  ! we assign the pointer to our array
                 ! in RecMergeSort we reference it just like an array
    call RecMergeSort(1,n) ! very similar to the findmin functions
    deallocate(work)
    return
end subroutine Sort

  • Dans notre programme principal tri est appelé comme ceci :
! our sort routine is also recursive but
! also shows a new usage for pointers
    call sort(results,num_genes)
    do j=1,num_genes
       write(*,"(f10.8,i4)")results(j)%val,   &
                            results(j)%index
    enddo

Cession de données avec les structures

! we can copy a whole structure
! with a single assignment
    best=results(1)
    write(*,*)"best result ",best

À l’aide de l’opérateur défini utilisateur

Cliquez ici pour savoir comment cette routine est définie

! using the user defined operator to see if best is worst
! recall that the operator .converged. checks to see if %index matches
    worst=>pntmin(results)
    write(*,*)"worst result ",worst
    write(*,*)"converged=",(best .converged. worst)


Passage de tableaux avec une basse donnée arbitraire limites

  • Motivation
  • Limite inférieure par défaut dans une sous-routine est 1
  • Pouvez utiliser une limite inférieure différente
    if(allocated(z))deallocate(z)
    allocate(z(-10:10)) ! a 21 element array
    do j=-10,10
       z(j)=j
    enddo! pass z and its lower bound
! in this routine we give the array a specific lower
! bound and show how to use a pointer to reference
! different parts of an array using different indices
  call boink1(z,lbound(z,1)) ! why not just lbound(z) instead of lbound(z,1)?
                             ! lbound(z) returns a rank 1 array
    subroutine boink1(a,n)
     use numz
     implicit none
     integer,intent(in) :: n
     real(b8),dimension(n:):: a ! this is how we set lower bounds in a subroutine
     write(*,*)lbound(a),ubound(a)
   end subroutine

AVERTISSEMENT : parce que nous sommes en utilisant un tableau de forme supposée nous devons une interface
Utilisant des pointeurs pour accéder aux sections de tableaux
  • Motivation
  • Peut augmenter l’efficacité
  • Peut augmenter la lisibilité
  call boink2(z,lbound(z,1))
 subroutine boink2(a,n) use numz
 implicit none
 integer,intent(in) :: n
 real(b8),dimension(n:),target:: a
 real(b8),dimension(:),pointer::b
     b=>a(n:) ! b(1) "points" to a(-10)
     write(*,*)"a(-10) =",a(-10),"b(1) =",b(1)
     b=>a(0:) ! b(1) "points" to a(0)
     write(*,*)"a(-6) =",a(-6),"b(-5) =",b(-5)end subroutine

Allocation d’un tableau à l’intérieur d’une sous-routine et en le passant en arrière

  • Motivation
  • Taille des tableaux sont calculées dans la sous-routine
module numz 
    integer, parameter:: b8 = selected_real_kind(14)
end module

program bla
   use numz
   real(b8), dimension(:) ,pointer :: xyz 
   interface boink 
     subroutine boink(a) 
     use numz
     implicit none 
     real(b8), dimension(:), pointer :: a 
     end subroutine 
   end interface 
   
   nullify(xyz) ! nullify sets a pointer to null 
   write(*,'(l5)')associated(xyz) ! is a pointer null, should be 
   call boink(xyz) 
   write(*,'(l5)',advance="no")associated(xyz) 
   if(associated(xyz))write(*,'(i5)')size(xyz) 
end program  

subroutine boink(a) 
    use numz 
    implicit none 
    real(b8),dimension(:),pointer:: a 
    if(associated(a))deallocate(a) 
    allocate(a(10)) 
end subroutine 

     F
     T     10


Notre fonction de remise en forme

Étant donné un nombre fixe de couleurs, M et une description d’une carte d’une collection d’États de N.
Trouver un coloriage de la carte tel qu’aucuns deux États qui partagent une frontière n’ont les mêmes couleurs.
Exemple d’entrée est une liste triée de 22 Etats de l’ouest
22
ar ok tx la mo xx
az ca nm ut nv xx
ca az nv or xx
co nm ut wy ne ks xx
ia mo ne sd mn xx
id wa or nv ut wy mt xx
ks ne co ok mo xx
la tx ar xx
mn ia sd nd xx
mo ar ok ks ne ia xx
mt wy id nd xx
nd mt sd wy xx
ne sd wy co ks mo ia xx
nm az co ok tx mn xx
nv ca or id ut az xx
ok ks nm tx ar mo xx
or ca wa id xx
sd nd wy ne ia mn xx
tx ok nm la ar xx
ut nv az co wy id xx
wa id or mt xx
wy co mt id ut nd sd ne xx
Notre fonction de remise en forme prend un potentiel Coloriage, c’est-à-dire un vecteur de nombre entier de longueur N et un renvoie le nombre de pensionnaires qui ont des États de la même coloration
  • Comment nous représentent sur la carte mémoire ?
  • Une solution consisterait à utiliser un tableau, mais il serait très clairsemée
  • Listes chaînées sont souvent une meilleure façon

Listes chaînées

  • Motivation
  • Nous avons une collection d’États et pour chaque État, une liste des États. (Ne pas compter un boarder deux fois.)
  • Problème, c’est que vous ne connaissez pas la longueur de la liste jusqu’au moment de l’exécution.
  • Liste des jouxtant les États sera de longueurs différentes pour différents États
  • Solution
  • Liste chaînée sont un bon moyen de gérer de telles situations
  • Listes chaînées utilisent un type de données dérivé au moins deux composantes
    • Données
    • Pointeur vers l’élément suivant

module list_stuff
    type llist
        integer index                ! data
        type(llist),pointer::next    ! pointer to the
                                     ! next element
    end type llist
end module

 


Utilisation de la liste chaînée

Remplir une liste liée consiste à utiliser une fonction récursive
    recursive subroutine insert (item, root)
    use list_stuff
    implicit none
    type(llist), pointer :: root
    integer item
    if (.not. associated(root)) then
        allocate(root)
        nullify(root%next)
        root%index = item
    else
        call insert(item,root%next)
    endif
end subroutine

Notre représentation de la carte

  • Un tableau des États de type de données dérivé
  • État est le nom d’un État
  • Liste chaînée contenant des pensionnaires
    type states
        character(len=2)name
        type(llist),pointer :: list
    end type states
  • Notes :
  • Nous disposons d’une série de listes chaînées
  • Cette structure de données est souvent utilisée pour représenter des baies rares
  • Nous pourrions avoir une liste liée de listes chaînées
  • Nom de l’État n’est pas vraiment nécessaire

  • Alica I/O de caractère et de progresser non

    Motivation

  • Nous avons lu les États à l’aide de l’identification de deux caractères
  • Une ligne par État et ne sais pas combien d’États boarder par ligne
  • Remarque : Notre liste des États est prétriée
      character(len=2) a     ! we have a character variable of length 2
      read(12,*)nstates      ! read the number of states
      allocate(map(nstates)) ! and allocate our map
      do i=1,nstates
        read(12,"(a2)",advance="no")map(i)%name ! read the name
        !write(*,*)"state:",map(i)%name
        nullify(map(i)%list)                    ! "zero out" our list
        do
        read(12,"(1x,a2)",advance="no")a      ! read list of states
                                              ! without going to the
                                              ! next line
            if(lge(a,"xx") .and. lle(a,"xx"))then  ! if state == xx
                backspace(12)                ! go to the next line
                read(12,"(1x,a2)",end=1)a    ! go to the next line
                exit
            endif
          1 continue
            if(llt(a,map(i)%name))then   ! we only add a state to
                                         ! our list if its name
                                         ! is before ours thus we
                                         ! only count boarders 1 time
! what we want put into  our linked list is an index
! into our map where we find the bordering state
! thus we do the search here
! any ideas on a better way of doing this search?
                found=-1
                do j=1,i-1
                    if(lge(a,map(j)%name) .and. lle(a,map(j)%name))then
                        !write(*,*)a
                        found=j
                        exit
                    endif
                enddo
                if(found == -1)then
                    write(*,*)"error"
                    stop
                endif
! found the index of the boarding state insert it into our list
! note we do the insert into the linked list for a particular state
                call insert(found,map(i)%list)
            endif
        enddo
       enddo

Fonctions de date et d’heure

  • Motivation
  • Voudrez peut-être connaître la date et l’heure de votre programme
  • Deux fonctions
   ! all arguments are optional
   call date_and_time(date=c_date, &  ! character(len=8) ccyymmdd
                      time=c_time, &  ! character(len=10) hhmmss.sss
                      zone=c_zone, &  ! character(len=10) +/-hhmm (time zone)
                      values=ivalues) ! integer ivalues(8) all of the above
   call system_clock(count=ic,        &  ! count of system clock (clicks)
                     count_rate=icr,  &  ! clicks / second
                     count_max=max_c)    ! max value for count

I/O  internes

  • Motivation
  • Devrez peut-être créer des chaînes à la volée
  • Devrez peut-être convertir des chaînes en nombres réels et des nombres entiers
  • Semblable à sprintf et sscanf
  • Comment ça marche
  • Créer une chaîne
  • Faire une écriture normale sauf l’écriture à la chaîne au lieu du numéro de dossier
  • Exemple 1: création d’une date et heure estampillée nom_du_fichier

     character (len=12)tmpstr
 
     write(tmpstr,"(a12)")(c_date(5:8)//c_time(1:4)//".dat") ! // does string concatination
     write(*,*)"name of file= ",tmpstr
     open(14,file=tmpstr)

     name of file= 03271114.dat

  • Exemple 2: Création d’une déclaration de format au moment de l’exécution (tableau d’entiers et un vrai)
     ! test_vect is an array that we do not know its length until run time
     nstate=9 ! the size of the array
     write(fstr,'("(",i4,"i1,1x,f10.5)")')nstates
     write(*,*)"format= ",fstr
     write(*,fstr)test_vect,result     format= (   9i1,1x,f10.5)

D’autres idées pour écrire un tableau lorsque vous ne connaissez pas sa longueur ?
  • Exemple 3: Lecture d’une chaîne
    integer ht,minut,sec
    read(c_time,"(3i2)")hr,minut,sec

S’enquérir de fonction

  • Motivation
  • Besoin d’obtenir des informations sur i/o
  • S’enquérir instruction comporte deux formes
  • Informations sur les fichiers (23 demandes différentes est possible)
  • Informations sur l’espace requis pour une sortie binaire d’une valeur
  • Exemple : trouver la taille de votre réel par rapport à la vraie “standard”
  • Utile pour les inter de programmation de langue
  • Utile pour déterminer les types de données en MPI (MPI_REAL ou MPI_DOUBLE_PRECISION)
        inquire(iolength=len_real)1.0
        inquire(iolength=len_b8)1.0_b8
        write(*,*)"len_b8  ",len_b8
        write(*,*)"len_real",len_real
        iratio=len_b8/len_real
        select case (iratio)
          case (1)
            my_mpi_type=mpi_real
          case(2)
             my_mpi_type=mpi_double_precision
          case default
            write(*,*)"type undefined"
            my_mpi_type=0
        end select  len_b8             2
 len_real           1 


NameList

  • Faisant maintenant partie de la norme
  • Motivation
  • Une méthode pratique de faire I/O
  • Bon pour le cas vous avez des pistes similaires mais changez une ou deux variables
  • Bon pour sortie mise en forme
  • Notes :
  • Un peu floconneuse
  • Pas d’options pour le format de la surcharge
  • Exemple :
       integer ncolor
       logical force
       namelist /the_input/ncolor,force
          ncolor=4
       force=.true.
       read(13,the_input)
       write(*,the_input)
    Sur entrée :
    &THE_INPUT NCOLOR=4,FORCE   = F /
    Sortie est
     &THE_INPUT
     NCOLOR  =           4,
     FORCE   = F
     /

    Fonctions vectorielles d’une valeur

    Motivation
    Voudrez peut-être une fonction qui renvoie un vecteur
    Notes
    Il faut encore une interface
    Utilisez le tableau de taille explicite ou supposée
    Ne pas retourner un pointeur à un vecteur sauf si vous voulez vraiment un pointeur
    Exemple :
    Prendre un vecteur d’entrée de nombre entier qui représente un nombre entier dans une base et ajouter 1
    Pourraient servir à notre programme de trouver une solution de « force brute »
    function add1(vector,max) result (rtn)
      integer, dimension(:),intent(in) ::  vector
      integer,dimension(size(vector)) :: rtn
      integer max
      integer len
      logical carry
      len=size(vector)
      rtn=vector
      i=0
      carry=.true.
      do while(carry)         ! just continue until we do not do a carry
          i=i+1
       rtn(i)=rtn(i)+1
       if(rtn(i) .gt. max)then
           if(i == len)then   ! role over set everything back to 0
            rtn=0
        else
            rtn(i)=0
           endif
       else
           carry=.false.
       endif
      enddo
    end function
    Usage        test_vect=0
            do
               test_vect=add1(test_vect,3)
               result=fitness(test_vect)
               if(result < 1.0_b8)then
                   write(*,*)test_vect
                   stop
               endif
            enddo


    Source complète pour les discussions récentes


    Exersize 5 modifier le programme à utiliser le générateur de nombres aléatoires donné plus tôt.


    Certaines fonctions intrinsèques spécifique de tableau

    TOUT vrai si toutes les valeurs sont vraies (logique)
    N’importe quel True si une valeur est true (logique)
    Nombre COUNT de vrais éléments dans un tableau (logique)
    DOT_PRODUCT Dot produit de deux matrices de rang 1
    Multiplication de matrices MATMUL
    Emplacement de la MAXLOC d’une valeur maximale dans un tableau
    Valeur maximale MAXVAL dans un tableau
    Emplacement de la MINLOC d’une valeur minimum dans un tableau
    Valeur MINVAL Minimum dans un tableau
    PACK Pack un tableau dans un tableau de rang un
    Produit d’éléments de tableau
    RESHAPE remodeler un tableau
    Tableau de réplicats de propagation en ajoutant une dimension
    Somme somme d’éléments du tableau
    TRANSPOSE transposer un tableau de rang deux
    Déballez déballer un tableau de rang un dans un tableau sous un masque
    Exemples

    program matrix
           real w(10),x(10),mat(10,10)
           call random_number(w)
           call random_number(mat)
           x=matmul(w,mat)   ! regular matrix multiply  USE IT
          write(*,'("dot(x,x)=",f10.5)'),dot_product(x,x)
    end program

     program allit
         character(len=10):: f1="(3l1)"
         character(len=10):: f2="(3i2)"
         integer b(2,3),c(2,3),one_d(6)
         logical l(2,3)
         one_d=(/ 1,3,5 , 2,4,6 /)
         b=transpose(reshape((/ 1,3,5 , 2,4,6 /),shape=(/3,2/)))
         C=transpose(reshape((/ 0,3,5 , 7,4,8 /),shape=(/3,2/)))
         l=(b.ne.c)
         write(*,f2)((b(i,j),j=1,3),i=1,2)
         write(*,*)
         write(*,f2)((c(i,j),j=1,3),i=1,2)
         write(*,*)
         write(*,f1)((l(i,j),j=1,3),i=1,2)
         write(*,*)
         write(*,f1)all ( b .ne. C ) !is .false.
         write(*,f1)all ( b .ne. C, DIM=1) !is [.true., .false., .false.]
         write(*,f1)all ( b .ne. C, DIM=2) !is [.false., .false.]
    end

    Le résultat est :
  1 3 5
 2 4 6
 
 0 3 5
 7 4 8
 
TFF
TFT
 
F
TFF
FF

Le reste de notre GA

  • Comprend
  • Reproduction
  • Mutation
  • Rien de nouveau dans un de ces fichiers
  • Source et makefile

Informations de compilateur

  • SGI
  • F90
  • suffix       *.f90
  • -64          create 64 bit programs (required on these machines)
  • man page is not up to date
  • found bugs in the compiler related to optional arguments
  • Cray T90
  • F90
  • suffix    *.f   *.f90
  • -r3        massive source listing (There are many options for listings)
  • -f free
  • -f fixed   The default is fixed for input files that end with a .f  The
  •            default is free for input files that end  with a .f90 suffix.
  • -O3        Highest general optimization
  • -Otask3    Multitasking optimization
  • -Ovector3  Highest vector optimization
  • Debugger   totalview
  • Profile    ja
  • Optimizer  xbrowse, perfview, jumpview
  • Cray T3e
  • F90
    • suffix    *.f   *.f90
    • -r3        massive source listing (There are many options for listings)
    • -f free
    • -f fixed   The default is fixed for input files that end with a .f  The
    •            default is free for input files that end  with a .f90 suffix.
    • -O3        Highest general optimization
    • Debugger   totalview
    • Optimizer  apprentice, pat
  • IBM SP2
  • xlf90
    • suffix       *.f
    • -O3          Highest level optimization with fast runtime but slow compile
    • -qfixed      Source is in fixed format
    • -qfree       Source is in free format (the default)
    • -qsource     Produce a source listing
    • -qarch=pwrx  Sets processor type pwrx, 604, 601
    • Debugger     xldb

Fortran 95

  • Nouvelles fonctionnalités
    • L’instruction FORALL comme alternative à l’instruction DO-
    • Imbrication partielle de FORALL et les déclarations
    • AILLEURS masqué
    • Procédures de pures
    • Procédures élémentaires
    • Procédures purs dans les expressions de la spécification
    • MAXLOC et MINLOC révisé
    • Extensions au plafond et le plancher avec l’argument de type mot clé
    • Initialisation de pointeur
    • Par défaut l’initialisation des objets de type dérivé
    • Compatibilité accrue avec l’arithmétique d’IEEE
    • Une sous-routine intrinsèque CPU_TIME
    • Une fonction NULL pour neutraliser le pointeur
    • Désallocation automatique de tableaux allouable à la sortie de l’unité de la portée
    • Commentaires dans NAMELIST d’entrée
    • Champ minimal d’entrée
    • Version complète de l’INTERFACE de fin
  • Fonctionnalités supprimées
    • véritable et double précision loop variables index
    • ramification si fin d’un bloc externe
    • Déclarations de PAUSE
    • ASSIGNER des déclarations et assigné aller à des déclarations et l’utilisation d’un entier assigné comme une spécification de FORMAT
    • Hollerith édition au FORMAT
  • Voir http://www.nsc.liu.se/~boein/f77to90/f95.html#17.5

Résumé

  • Fortran 90 a des caractéristiques à :
  • Améliorer les performances
  • Portabilité
  • Améliorer la fiabilité
  • Améliorer la maintenabilité
  • Fortran 90 a de nouveaux éléments de langage
  • Forme de la source
  • Types de données dérivés
  • Fonctions d’allocation de mémoire dynamique
  • Aimable facilité la portabilité et modification facile
  • Beaucoup de nouvelle fonction intrinsèque
  • Affectations de tableau
  • Exemples
  • Aider à montrer comment les choses fonctionnent
  • Référence pour une utilisation future

Références


 

Comments are closed.