Precedente | Indice | Successivo |
Scopo: | calcolo dell'integrale definito di una funzione reale di variabile reale |
Specifiche: |
subroutine quad (f, a, b, tol, hmin, nmax, q, e, nval, ifail) integer nmax, nval, ifail real f, a, b, tol, hmin, q, e |
Descrizione: |
Backgroud del problema
Il problema è quello di fornire una stima approssimata dell'integrale definito di una funzione reale di una variabile reale, e una stima dell'errore commesso nel passaggio dal continuo al discreto. Descrizione dell'algoritmo L'algoritmo implementa un procedimento di quadratura automatica adattativa, che consta di un modulo di quadratura locale (LQM), in questo caso il modulo Cavalieri-Simpson, di una strategia per selezionare il sottointervallo da suddividere ad ogni passo, e di un criterio di arresto. La strategia adottata per la scelta dell'intervallo è di tipo locale, suddivide l'intervallo di lavoro solo nel caso in cui l'errore ad esso relativo derivante dall'applicazione dell'LQM è maggiore della tolleranza accettata per quell'intervallo (in base alla sua ampiezza); per contrastare poi la tendenza naturale dell'algoritmo ad infittire il calcolo nel caso in cui la tolleranza inserita sia molto piccola, si preferisce richiedere in ingresso anche una misura dell'ampiezza minima alla quale si può ridurre un intervallo di integrazione nonché un numero massimo di valutazioni eseguibili. La gestione dei sottointervalli di integrazione è eseguita per mezzo di una pila che ha nel top l'intervallo di ampiezza minore. Ogni qualvolta un intervallo è scaricato dalla pila, cioè quando l'errore dell'LQM è minore della tolleranza relativa al sottointervallo di calcolo, è aggiunto al valore dell'integrale Q ed a quello dell'errore E il contributo locale calcolato. L'algoritmo termina o per lo svuotamento della pila o per il raggiungimento del numero massimo di valutazioni consentite. Raccomandazioni sull'uso La tolleranza inserita deve essere non negativa. Il numero massimo di valutazioni eseguibili deve essere maggiore di cinque. Il passo minimo di integrazione deve essere positivo e minore dell'ampiezza dell'intervallo di integrazione |
Bibliografia: | [1], [2] |
Parametri di I/O: |
input
f - funzione integranda output
q - reale, valore approssimato dell'integrale |
Indicatori d'errore: |
Errori gestiti dalla subroutine: ifail = 0 nessun errore. ifail = 2 la tolleranza assoluta inserita non è valida ifail = 16 il numero di valutazioni richieste non è valido ifail = 17 il passo minimo di integrazione non è valido ifail = 18 lo stack per la gestione degli intervalli è pieno ifail = 19 il numero massimo di valutazioni è stato raggiunto |
Routines ausiliarie: |
eps, funzione reale, calcolo dell'epsilon macchina simp, funzione reale, formula di Cavalieri-Simpson tolm, funzione reale, tolleranza relativa |
Tempo d'esecuzione: | dipende dal numero e dalla complessità di valutazioni di f, dalla tolleranza richiesta e dal passo minimo d'integrazione. |
Memoria richiesta: | un array allocato per gestire la pila. |
Accuratezza fornita: | l'accuratezza è funzione della tolleranza assoluta inserita dall'utente e dal numero massimo di valutazioni consentite. |
Esempio di programma chiamante: |
Program quadd c Programma dimostrativo della subroutine quad external quad real f1,f2,f3,f4,f5 external f1,f2,f3,f4,f5 integer dim parameter (dim=25) real a,b,tol,hmin,q,e,x(dim),y(dim) integer nmax,nval,ifail character risp character*12 fin,fout logical warn print*,'*** PROGRAMMA DIMOSTRATIVO DELLA SUBROUTINE QUAD ***' print* 10 continue print*,'Funzione integranda :' print* print*,'1) sin(x)' print* print*,'2) (100/x**2)*sin(10/x)' print* print*,'3) 10*(x-1)*(x-0.5)*(x-0.25)*(x-0.125)*(x-0.0625)', % '*(x-.03125)' print* print*,'4) 1/sqrt(x)' print* print*,'5) e^(-x^2)' print* print*,'Numero della funzione= ' read(*,*)n print*,'Integrale definito/indefinito [d/i]= ' read(*,'(A)')risp if (risp .eq. 'd') then print*,'Estremi d''integrazione= ' read(*,*)a,b num=1 endif if (risp .eq. 'i') then print*,'Punto iniziale= ' read(*,*)a print*,'Valore iniziale= ' read(*,*)Fa print*,'Numero di punti di valutazione= ' read(*,*)num print*,'Nome del file di input = ' read(*,'(A)')fin open(11,FILE=fin,STATUS='OLD') do 15 i=1,num read(11,*)x(i) 15 continue close(11) endif print*,'Tolleranza richiesta= ' read(*,*)tol print*,'Passo minimo d''integrazione= ' read(*,*)hmin print*,'Numero massimo di valutazioni (minimo 5)= ' read(*,*)nmax warn=.false. do 20 i=1,num if (risp .eq. 'i') b=x(i) if (n .eq. 1) % call quad(f1,a,b,tol,hmin,nmax,q,e,nval,ifail) if (n .eq. 2) % call quad(f2,a,b,tol,hmin,nmax,q,e,nval,ifail) if (n .eq. 3) % call quad(f3,a,b,tol,hmin,nmax,q,e,nval,ifail) if (n .eq. 4) % call quad(f4,a,b,tol,hmin,nmax,q,e,nval,ifail) if (n .eq. 5) % call quad(f5,a,b,tol,hmin,nmax,q,e,nval,ifail) if (ifail .eq. 2) % print*,'Errore! tolleranza assoluta non valida' if (ifail .eq. 16) % print*,'Errore! numero di valutazioni non valido' if (ifail .eq. 17) % print*,'Errore! passo minimo d''integrazione non valido' if (ifail .eq. 18) % print*,'Errore! stack overflow' if (ifail .ge. 2 .and. ifail .le. 18) goto 30 if (ifail .eq. 19) warn=.true. if (risp .eq. 'i') y(i)=Fa+q 20 continue if (warn) then print*,'Attenzione! raggiunto il numero massimo ', % 'di valutazioni' print* endif if (risp .eq. 'd') then write(*,40)'Stima dell''integrale= ',q print* write(*,40)'Stima dell''errore= ',e print* write(*,50)'Valutazioni effettuate= ',nval endif if (risp .eq. 'i') then print*,'Nome del file di output=' read(*,'(A)')fout open(12,FILE=fout) write(12,60)(y(i),i=1,num) close(12) print*,'Valutazione approssimata dell''integrale ', % 'indefinito nei punti assegnati:' write(*,60)(y(i),i=1,num) endif 30 print* print*,'c per continuare, un altro carattere per terminare:' read(*,'(A)')risp if (risp .eq. 'c') goto 10 40 format(1X,A,E14.7) 50 format(1X,A,I6) 60 format(1X,E14.7) End |
Precedente | Indice | Successivo |