Fortran – i moduli

I moduli sono il punto d’arrivo di una linea di sviluppo antica. Probabilmente conviene esaminarne i vari componenti per comprenderne l’utilità e la bellezza.
Le procedure, funzioni e subroutine, hanno diversi scopi:

  • riusare blocchi di codice;
  • ripetere operazioni con set diversi di dati;
  • evitare conflitti tra le variabili
  • semplificare lo sviluppo (divide et impera).

Il loro posto naturale sono i moduli; inoltre questi possono contenere costanti (parameter), variabili, arrays, structures. In questo caso il modulo supera il common, in modo più flessibile. Eccone un esempio.

program e_com !esempio d'uso di common

implicit none
common /my_common/ intv, realv, complv

integer :: intv
real :: realv
complex :: complv

intv = 21
realv = 24.6
complv = (3, 4)

print *, 'inizio'
print *, intv, realv
print *,  complv

call doppio

print *, 'dopo'
print *, intv, realv
print *,  complv

end

subroutine doppio

implicit none
common /my_common/ intv, realv, complv

integer :: intv
real :: realv, re, im
complex :: complv
character :: nl =  new_line(' ')

print *, nl, 'doppio', nl

intv = 2 * intv
realv = 2 * realv
re = 2.0 * real(complv)
im = 2.0 * aimag(complv)
complv = complex(re, im)

end


Lo stresso programma riscritto usando un modulo

program e_mod !esempio d'uso di modulo

use m_mod
implicit none

intv = 21
realv = 24.6
complv = (3, 4)

print *, 'inizio'
print *, intv, realv
print *,  complv

call doppio

print *, 'dopo'
print *, intv, realv
print *,  complv

end

e

module m_mod

implicit none
save
integer :: intv
real :: realv
complex :: complv

contains
    subroutine doppio

    real :: re, im
    character :: nl =  new_line(' ')

    print *, nl, 'doppio', nl

    intv = 2 * intv
    realv = 2 * realv
    re = 2.0 * real(complv)
    im = 2.0 * aimag(complv)
    complv = complex(re, im)

    end subroutine doppio

end module m_mod

Con i moduli si possono scrivere procedure polimorfe, simili a quelle predefinite. Fin dall’antichità (quasi) si può usare, per esempio, max() al posto di amax0(), amax1(), max0() e max1(). Adesso si possono costruire! Ecco un esempio, preso da TACC, la funzione swap().

module mod_swap
public  swap
private swap_real, swap_integer

interface swap
    module procedure swap_real, swap_integer
end interface

contains
    subroutine swap_real(x, y)
    real :: x, y, t
    t = x
    x = y
    y = t
    end subroutine swap_real

    subroutine swap_integer(i, j)
    integer :: i, j, k
    k = i
    i = j
    j = k
    end subroutine swap_integer

end module mod_swap

 

program p_swap
use mod_swap

real :: a = 3., b = 4.
integer :: i = 1, j = 2

call swap(a, b)
print *, a, b

call swap(i, j)
print *, i, j

end

Posso definire operatori, ecco .plus. che fa la somma di due interi

module mod_op

public  :: operator(.plus.)
private :: f_plus
    interface operator(.plus.)
        module procedure f_plus
    end interface
contains
    function f_plus(x, y) result(res)
    integer, intent(in) :: x, y
    integer :: res
    res = x + y
    end function
end module

 

program p_op
use mod_op

i = 3
j = 5
print *, i, j, i .plus. j

end


Esistono inoltre le funzioni elemental, questa è una parola magica che estende la funzione agli array

module m_quad
contains
    elemental function quad(x) result (q)
    real, intent(in) :: x
    real :: q
    q = x * x
    end function
end module
program p_quad
use m_quad

real :: t = 12.
real, dimension(3) :: v = [1., 2., 3.]

print *, t, quad(t)
print *, v
print *, quad(v)

end


Durante la compilazione di un modulo viene creato un file .mod. Devo ancora capire quando viene utilizzato, se si rimuove l’eseguibile funziona ugualmente. Sono file di testo, che iniziano in questo modo:

GFORTRAN module version '6' created from m_mod.f08 on Mon Jun 25 09:10:02 2012
MD5:09d3ef60d0503441cdee588ae159073e -- If you edit this, you'll get what you deserve.

Prossimamente, forse ;-)

About these ads
Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • glipari  Il 06/26/2012 alle 12:23

    Sta diventando un linguaggio molto bello!! :)

Lascia un Commento

Fill in your details below or click an icon to log in:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Connessione a %s...

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Unisciti agli altri 37 follower

%d bloggers like this: