Newsgroup: it.scienza.fisica
Titolo: Fortran e precisione nei calcoli

Ciao a tutti!
        Scusate la lunghezza del post, ma ho dubbio su come migliorare
l'approssimazione dei calcoli di un programma che ho scritto in  Fortran
90 per agevolarmi la vita, ma che in realtà non ha ancora espresso le
sue potenzialità.
        Il dubbio è presto detto: ho un campione di dati e ne devo
calcolare il relativo generico scarato medio, lo scarto quadratico
medio, il rapporto tra i precedenti valori, ecc...
        I dati sperimentali sono discreti al decimo di centimetro (la
media è 7.4cm). Ho inizializzato l'array contente i dati sperimentali
come REAL (KIND=4), e  forse è questo che sbaglio. 
        Per calcolare i generici scarti, sottraggo ad ogni valore
sperimentale la media aritmetica. Divido poi per il numero delle misure
e trovo  il generico scarto medio (theta). 
        Se stampo a monitor i  risultati degli scarti per ogni singolo
valore sperimentale, vedo che i calcoli hanno una pesante
approssimazione, per esempio:
Valore Sperimentale             Media           Scarto
6.7                     6.6             9.999971E-02
6.3                     6.6             -0.2999999
6.6                     6.6             -0.6000001
7.0                     6.6             0.3999999
Mi rendo conto di quanto poco  varia lo scarto, ma vi  assicuro che
quegli errori si ripercuotono al centesimo sullo  scarto quadratico
medio e  su altri  valori... al punto da ottenere un determinato valore
di aspettazione come 0.41231 al posto di 0.67...
Allora,  chiedo, c'è un modo per aumentare le  cifre dopo la virgola?
Basterebbero  anche  12  cifre  decimali, credo, per abbattere in  buona
misura l'approssimazione (forse  KIND=8, o qualcosa di simile?). Oppure,
c'è un modo per formattare i valori  alla approssimazione voluta?
Scusate le domande, forse banali, ma sono un po' autodidatta... :-)
PS: Scusate se posto sia in *.fisica  c he in *.matematica, ma non sono
sicuro di chi sarebbe stata la competenza...
__________________________
H A L

 sicuro di chi sarebbe stata la competenza...
Di nessuno dei due. Dovresti provare su comp.lang.fortran oppure su
it.comp.programmare
Comunque: usa dei REAL*8 : usare 4 bytes per i reali non ha praticamente
senso (in termini di precisione e velocita') a meno che tu non debba
memorizzare milioni e milioni di questi numeri risparmiando sulla
memoria.
ciao,
g.

 come REAL (KIND=4), e  forse è questo che sbaglio.
usa
     INTEGER, PARAMETER   :: dp = SELECTED_REAL_KIND(15, 300)
dove dp e' una costante che indica la precisione con 15 cifre decimali e 300
per massimo esponente
per dichiarare una variabile in doppia precisione usa
  REAL (dp) :: nomevariabile
per dichiarare invece le costanti in doppia precisione:
  REAL (dp), PARAMETER :: pi = 3.141592654_dp
Ciao
Giacomo

 memoria.
Ok per la motivazione, ma non ho capito come scrivi... è proprio
REAL*8:: ecc   o REAL (KIND=8):: ecc  ?
Grazie mille per la cortesia,
buon pomeriggio!
__________________________
H A L

 sicuro di chi sarebbe stata la competenza...
E' un problema interdisciplinare e i fisici dovrebbero essere ben 
piazzati per aiutarti.
Giorgio

   REAL (dp), PARAMETER :: pi = 3.141592654_dp
__________________________
H A L

 
In  che senso per le costanti? I PARAMETER non li assegni tu all'inizio
quando inizializzi il tutto?
Infine (prometto!!) c'è qualche dispensa, anche in inglese, su cui poter
studiare un po' di teoria? Un pdf da scaricare su Fortran... Mi hanno
consigliato una dispensa di Liverpool University, ma non ho trovato
nulla di scaricabile... Solo una completa guida html...
Grazie mille per la cortesia,
HAL
_________________________
H A L

 0,2999999    ma  non me lo fa....
Premetto che sono "rimasto" al FORTRAN 77, con cui ho programmato parecchio
negli anni '80, ma non credo che su questo fronte le cose siano cambiate
molto.
Quando ragioni con i reali, indipendentemente dalla precisione che ti serve,
devi ricordarti sempre che "uno più uno fa circa due". Questo è legato alla
rappresentazione binaria interna e non ci puoi fare nulla.
Ad esempio è pericolosissimo fare test del tipo IF (A .EQ. B) THEN...
Conviene quindi definire un PARAMETER EPSILON pari al valore più piccolo
rappresentabile nel livello di precisione prescelto (REAL, DOUBLE PRECISION
o più) e poi impostare:
IF (DMOD(A-B) .LE. EPSILON) THEN...
DMOD vale se A e B sono DOUBLE PRECISION (cioè REAL*8), mentre se A e B sono
REAL (cioè REAL*4) devi invece usare AMOD.
Per inciso, questi problemi ci sono anche con le banali calcolatrici da
pochi soldi, tipo euroconvertitori, per intendersi.
Se fai 10 / 3 * 3 otterrai un bel 9,9999999 sul display.
Invece se usi calcolatrici più evolute, tipo quelle scientifiche, invece ti
troverai di nuovo 10 come risposta.
Questo perché queste calcolatrici hanno internamente tre cifre in più di
quelle che compaiono suil display. Alla fine del calcolo, prima di essere
messo sul display, il risultato viene arrotondato con il sistema 4/5
buttando via le tre cifre invisibili.
Ciao!
 
-- 
Roberto Rosoni
<roberto...@liberoLock.it> (Remove the Lock in your replies)
 
"Caro, perché non giochi un po' a calcio coi bambini?" "Perché rimbalzano male."
 

 nulla di scaricabile... Solo una completa guida html...
Dipende da dove parti. Per chi viene dal mondo del f77 c'e' un tutorial 
on line con anche una versione scaricabile zippata a:
http://www.nsc.liu.se/~boein/f77to90/f77to90.html
Per i tuoi dubbi sulla precisione consiglierei pero' il link su  "The 
Perils of Floating Point", Bruce M. Bush nella pagina
http://www.lahey.com/other.htm
che e' una buona miniera di altre informazioni sul fortran.
Se hai richieste piu' precise, fai pure un fischio...
Ciao
Giorgio

 andavano considerate a 64 bit.
Se fai:
DOUBLE PRECISION PI
PI = DACOS (-1.)
In PI ti trovi pi greco a 64 bit. Anzi sono convinto che accada anche se usi
ACOS() perché il compilatore vede che deve caricare un doppiaprecisione e
sceglie la giusta mathfunc.
Inoltre -1. e -1.D0 hanno lo stesso esponente e la stessa mantissa binaria:
nel secondo hai solo 32 zeri in piů nella mantissa, irrilevanti quindi come
argomento di input alla funzione.
Non so con quelle barzellette che erano i compilatori IBM dei /370, ma con
quelli Digital (GRANDE Digital!) era cosě. 
Ciao!
 
-- 
Roberto Rosoni
<roberto...@liberoLock.it> (Remove the Lock in your replies)
 
I Veri Programmatori non muoiono mai, al massimo saltano ad un nuovo indirizzo.
 

 quelli Digital (GRANDE Digital!) era cosė. 
Beh, i compilatori digital (ma ora la stessa tecnologia e' finita in 
quelli Intel !!) erano e sono dei gran bei compilatori. Pero' ti 
assicuro che, barzellette o storie dell' orrore a parte neanche i 
compilatori dei 370 scherzavano, almeno quanto a robustezza....
Ciao
Giorgio

 compilatori dei 370 scherzavano, almeno quanto a robustezza....
Sulla robustezza del codice prodotto concordo, ma il FORTRAN dei /370 era
noto per non perdonare, soprattutto per colpa del SO sottostante (MVS contro
VMS, e come sai non č una semplice permutazione di lettere).
Se non inizializzavi una variabile, il VMS te l'allocava comunque su una
pagina demand-zero mentre l'MVS su una pagina di bit casuali. Concordo sul
fatto che č una cazzata di programmazione il dimenticare
un'inizializzazione, ma sai che gioia debuggare un programma che ti da
risultati differenti di run in run...
Ciao!
 
-- 
Roberto Rosoni
<roberto...@liberoLock.it> (Remove the Lock in your replies)
 
"Stai programmando in Pascal?" - "No, č C." - "Salute!"
 

 anomalo...)
Appena  ho un attimo provo, così li pongo in relazione.
Per  ora  grazie  a tutti per le chiarissime e disponibili risposte!
Davvero! Buona serata!!
__________________________
H A L

 H A L
Certo che dei dubbi così da uno che si chiama H A L...
Hai pensato di cambiare il tuo nick in PALLOTTOLIERE?!? ;-)
Scusa la battutaccia, non ho resistito!
Ciao!
 
-- 
Roberto Rosoni
<roberto...@liberoLock.it> (Remove the Lock in your replies)
 
Noi Elaboratori della Serie 9000 siamo incapaci di sbagliare (2001ASO)
 

 Scusa la battutaccia, non ho resistito!
....per questa volta... :-) Tranquillo! E' la verità :-)
__________________________
H A L