Scrivere un programma che integri la funzione x4 tra 0
e 1 mediante due sottoprogrammi (uno di tipo function e uno subroutine) che
implementino rispettivamente la formula trapezoidale e quella di Simpson .
La funzione integranda deve essere calcolata in una function
di un argomento real il cui nome sarà passato come argomento
alla procedura che valuta l' integrale. Una procedura
Fortran (subroutine o function) può avere tra i
suoi
argomenti il nome di un'altra procedura. Questo argomento va dichiarato nel
sottoprogramma mediante un' interfaccia esplicita(*).
Verificare
l' accuratezza del risultato in funzione del numero di punti, e della
precisione dei real, partendo
da una decina di punti fino a qualche milione. Si
ricorda che la formula trapezoidale (estesa) corrisponde a sommare i valori
della funzione su punti equispaziati, a distanza h, attribuendo a
ciascuno un peso h,
tranne gli estremi che intervengono con peso h/2. La formula di
Simpson
(estesa) fa invece intervenire pesi
h/3,4h/3,2h/3,4h/3,2h/3,...,4h/3,h/3 e
quindi
presuppone un numero dispari di punti (ovvero un numero pari di intervallini). In
particolare
andrà verificata la dipendenza dell' accuratezza
dell' integrale dal numero di punti. Si ricorda che l'
errore algoritmico del metodo trapezoidale va a zero con 1/N2,
mentre
nel
caso
Cavalieri-Simpson
la
dipendenza
è
1/N4, per funzioni con derivata seconda e quarta limitata, rispettivamente.
(*) Esempio:
module prec
integer, parameter :: rk= selected_real_kind(6)
end module prec
module funzi
use prec
implicit none
contains
function f(fun,a,b) result (r)
real(kind=rk),intent(in) :: a,b
real(kind=rk) :: r
interface
function fun(x) result(res)
use prec
real(kind=rk), intent(in) :: x
real(kind=rk) :: res
end function fun
end interface
.....
end function f
function fun1(x) result(r1)
...
end function fun1
function fun2(x) result(r1)
...
end function fun2
end module funzi
program pippo
use funzi
implicit none
real(kind=rk) :: q,s,a,b
...
q=f(fun1,a,b)
s=f(fun2,a,b)
...
dove fun1 e fun2 sono funzioni con la stessa interfaccia di fun.
Istogrammi.
Scrivere un programma che generi N variabili casuali, ognuna delle quali sia la media aritmetica di 100 numeri casuali distribuiti uniformemente tra 0 e 1. Si ricorda che la subroutine intrinseca random_number(x), chiamata con argomento scalare o array, ritorna uno o più valori real distribuiti uniformemente tra 0 e 1.Ciascun numero così generato dovrà essere scritto in un file di nome DATI.
Il file deve quindi essere chiuso dal programma e riaperto in sola lettura. Il programma deve quindi leggere i dati e costruire un istogramma delle frequenze dei dati su 100 intervalli di ampiezza 1 tra 0 e 1.
Il seguente frammento di codice gestisce la creazione dell' istogramma. Può essee utilizzato per costruire il programma completo.
real :: dx, xmin, xmax
real :: dato
integer,dimension(:),allocatable :: histo
integer :: i,ind,fuori,nbin,Ndati ! Ndati rappresenta il numero dei dati nel file
! nbin il numero dei canali (intervallini) dell' istogramma.
! generazione di Ndati numeri casuali ottenuti sommando 100 n. casuali
! distribuiti uniformemente tra 0 e 1 e scrittura deglistessi su file di nome DATI
! chiusura del file e riapertura in lettura
print*,' xmin, xmax, nbin:? '
read*, xmin, xmax, nbin
allocate(histo(nbin))
histo = 0
fuori = 0
dx = (xmax-xmin)/nbin
do i = 1,Ndati
read(1,*)dato
ind = int((dato-xmin)/dx) + 1
if ( ind>nbin .or. ind <1)then
fuori = fuori + 1
else
histo(ind) = histo(ind) + 1
end if
end do
do i=1,nbin
write(2,*) i, xmin+(i-1)*dx+dx/2,real(histo(i))/Ndati*nbin
end do
print*,
print*,"# fuori: ", fuori
L'istogramma, i cui dati saranno su file fort.2, può essee graficato con gnuplot col comando
plot [0:1] 'fort.2' u 2:3 w boxes fs solid .5
Verificare l'effetto di variare il parametro .5 tra 0 e 1. E anche l'effetto di dare il comando
set boxw 0.6 relative
prima del comando plot.