Newsgroup: it.comp.lang.c
Titolo: COME SI REALIAZZA IL GRADIENTE O DERIVATA

Volevo sapere se qualcuno conosceva il modo per effettuare le derivate
parziali di una funzione F(x)=f(x1,x2,..,xn) in modo da poter realizzare il
gradiente della funzione.
Vorrei sapere se e' possibile effettuare la derivata simbolica o soltanto
quella in un punto

 quella in un punto
Qui siamo su tutto un altro ordine di complessita', si puo' fare ma la
difficolta' non e' nemmeno paragonabile con quanto scritto prima.
Ciao.
-- 
     (ZZZ)       Filippo Salotti, Bagni di Lucca, Lucca, Italy.
    //   \\  _                 E-mail : 
fil...@humnet.unipi.it
   /Y\    ZD<_o===============================================o
 .oZZZZZo.     | Studente Ingegneria Informatica Automatica  |
<OXXXXXXXO>    | Dip. Sistemi Elettrici Universita' di Pisa. |

difficolta' non e' nemmeno paragonabile con quanto scritto prima.
Gia`.  Pero`, se si desiderano risultati numerici di discreta
precisione, e con affidabilita`, allora la difficolta` del calcolo
puramente numerico della derivata cresce parecchio; se la
funzione F e` ragionevolmente rappresentabile in modo
analitico (polinomio approssimante, funzione razionale, ecc),
allora la "derivata simbolica" (ad uso numerico) puo` essere
il modo piu` semplice di procedere.  Gli unici problemi seri
con la derivazione simbolica sono quello dell'input e
dell'output delle funzioni in forma accettabile all'utente
(normalmente occorre una semplificazione; pochi utenti
sono contenti di accettare "1*x + 0" come derivata di
"0.5 * x + 3"...!-); se serve solo il valore numerico, il
problema dell'output e della semplificazione puo` essere
ignorato (resta quello dell'input... la semplificazione puo`
servire per ragioni di prestazioni, se la derivata va poi
calcolata in molti punti).
Alex

 il modo piu` semplice di procedere. 
E' chiaro che la derivata simbolica e' sicuramente meglio e se non se
puo' fare a meno va implementata ma il tutto e' molto complesso da
relizzare specie se la F non ha particolari proprieta' (es. non e' un
polinomio).


polinomio).
Le funzioni che non sono polinomi possono pero` essere
approssimate da polinomi... meglio di come non possano
essere approssimate da una assoluta linearizzazione!  Con
le funzioni razionali, poi (rapporti di polinomi, pur sempre
agevolmente differenziabili), si arriva ad approssimazioni
ancora migliori.
Valutare una funzione in due punti x e x+dx, e decidere di
approssimare la derivata sulla base di questi due soli valori,
equivale, come e` geometricamente chiaro, ad approssimare
la funzione con un polinomio di ordine 1 (a x + b) _E_ a
scegliere a e b sulla base di due soli punti; ciascuna di queste
due scelte e` gia` di per se assai discutibile.
Perche` e percome un polinomio di ordine N, non _troppo_
grande ma comunque >1, sia un'approssimazione migliore
di quella che N==1 puo` offrire, spero che sia gia` abbastanza
chiaro "intuitivamente" (certo, in analisi numerica, l'intuizione
tende MOLTO spesso ad ingannare; non per nulla e` forse
l'area piu` diabolicamente difficile di tutta l'informatica).  In
pratica, un N fra 2 e 4 tende ad essere la scelta migliore per
la maggior parte delle funzioni (in piccoli intorni).
Ancora piu` importante e` rendersi conto che, avendo
deciso di approssimare una funzione in un intorno con
un polinomio di ordine N, e` *numericamente disastroso*
valutare la funzione stessa in soli N punti, e scegliere
proprio quell'unico polinomio che passa per gli N punti
(Xi, f(Xi)) per i da 1 a N.  La _imprecisione numerica_
nel calcolo di anche uno solo di questi punti rende il
"polinomio interpolante" praticamente inutilizzabile.
Meglio, se mai, scegliere *parecchi* punti in piu` (di
solito, almeno 2N circa), e prendere come polinomio
interpolante quello che minimizza una metrica d'errore
rispetto agli M>N punti.  Minimizzare l'errore massimo
(Chebichev) non e` ancora l'ideale (soprattutto non per
il calcolo della derivata in presenza di approssimazioni
numeriche); minimizzare la somma dei quadrati degli
errori e` gia` assai meglio.
Buone URL per queste problematiche in generale:
http://www.physics.carleton.ca/courses/75.502/slides/intro/numerical/index.html
http://beta.ul.cs.cmu.edu/webRoot/Books/Numerical_Recipes/
Per chi abbia un lettore Adobe PDF connesso al proprio
browser, e sia interessato al tema specifico "calcolo
numerico della derivata", merita inoltre visitare, in
particolare, la URL:
http://beta.ul.cs.cmu.edu/webRoot/Books/Numerical_Recipes/bookcpdf/c5-7.pdf
che, della formula da te proposta per il calcolo della derivata,
dice (traduco):
"""
Applicata acriticamente, e` quasi garantito che questa procedura
produrra` risultati inaccurati.  Applicata correttamente, puo` essere
il modo giusto di calcolare una derivata solamente se la funzione
f e` FEROCEMENTE costosa da calcolare, quando hai gia`
investito nel calcolare f(x) e quando, dunque, vuoi ottenere la
derivata con non piu` di una ulteriore valutazione della funzione.
"""
dopo di che, supponendo che tutte queste ipotesi siano vere,
passa a discutere il problema di come scegliere l'epsilon (che
tu chiami d, e il testo chiama h), cui dedica poco piu` di una
ulteriore pagina; poi, passa a formule migliori, sia basate su
ordini superiori di differenze finite (equivalenti a migliori
approssimazioni polinomiali), sia su idee piu` avanzate,
sino alla implementazione per approssimazione di Ridders
dell'idea generale dell'approccio-al-limite alla Richardson
(con "quadro di Neville" per l'estrapolazione).  Del metodo
di Ridders da` anche una completa implementazione in C.
Prosegue accennando a metodi basati su Chebichev (cui
sono poi dedicati i due successivi sottocapitoli 5.8 e 5.9),
e a quelli basati su filtri di Savitzky-Golay (che andranno poi
approfonditi parecchi capitoli piu` avanti).
"Numerical Recipes" (nelle edizioni C e Fortran) e` un
testo di analisi numerica molto pragmatico ed elementare,
ma decisamente consigliabile rispetto all'alternativa di
affidarsi, per simili diabolici problemi, a una qualche vaga
intuizione aritmetica personale; e` quindi particolarmente
fortunato che al giorno d'oggi sia disponibile in linea (anche
se continuo a consigliare di comprarsene anche una copia
cartacea a chiunque si trovi occasionalmente di fronte a
problemi pratici di calcolo numerico...!).
Alex

quella in un punto
fatte salve le osservazioni di Alex ricordare la REGOLA N. 1 della
derivazione numerica:
Scegliere sempre h in modo t.c. che x ed x + h differiscano per un
numero esattamente rappresentabile dalla macchina!
	temp = x + h;
	h= temp -x;
Estratto dalla Bibbia: Numerical Recipes in C.

precisione di tuoi calcoli.
D'accordo, questo e' il classico procedimento del rapporto incrementale che
tende alla derivata nel punto dato per d che tende a zero, ma non porta
sicuramente a un risultato accettabile dal punto di vista della precisione.
Il calcolo e' fonte di perdita di precisione per due ragioni : la differenza di
numeri molto vicini e, sopratutto, la divisione tra numeri molto vicini.
Andrea (mica uno qualunque...)
------------------------------
(se mi mandi la spam ti metto un'aspirina nella fanta...)
--
Posted from 
itaca.ulysse.it
 [195.223.254.1]
via Mailgate.ORG Server - 
http://www.mailgate.org

"0.5 * x + 3"...!-);
Hai saltato un esponente :) 
1 * x + 0 e' la derivata di 0.5 * x^2 + cost. 


...e poi fare una prova per vedere se basta si fa cosi presto...
Il problema, dal mio punto di vista, e' una propagazione di errori nei calcoli.
Se la questione si limita a un semplice calcolo della derivata cio' che dici
potrebbe andare bene, pero' immagina di utilizzare il calcolo della derivata
come fattore in calcoli ulteriori.
Gia' il fatto di compiere la derivata su funzioni come il logaritmo, o il seno o
il coseno che a livello di implementazione sono ottenute mediante
approssimazioni con serie numeriche, conduce ad una prima perdita di precisione.
Calcolare la derivata in modo impreciso su queste funzioni porta ad una
ulteriore perdita con conseguente propagazione di errori di precisione.
