PDA

Visualizza la versione completa : [C] Zeri di una funzione


Toxotes
18-01-2011, 13:22
Salve, qualcuno mi saprebbe consigliare una funzione di una qualche libreria per cercare gli zeri di una funzione con precisione alta (tipo > 1.e-50). Grazie ciao.

Laikius91
18-01-2011, 15:24
Esiste? mmmm..

Perchè non la realizzi tu? Non è troppo complicata e puoi darle la precisione che vuoi..
In genere si usa il metodo di bisezione!

deleted_29
18-01-2011, 16:49
ahem... ahemmmmm^2... diciamo che è uno dei campi di massima ricerca (e massima difficoltà) dell'informatica.

dipende tutto dalla funzione; la bisezione, ad esempio, va bene per funzioni continue.
---
riguardo poi alla percisione ti segnalo che quella che hai messo è talmente elevata da essere sostanzialmente irrealistica, anche sotto il profilo dell'utilizzo di numeri float "normali" e non a precisione "manualmente superestesa".
gli errori numerici sono così grandi che, in sintesi, avresti gravissimi problema di stabilità, con eps così piccolo

Toxotes
18-01-2011, 16:52
Certo che potrei...ma ne ho già una delle numerical recipies che penso sia fatta meglio di qualsiasi funzione io possa scrivere. Per lavorare con precisioni così alte penso ci sia bisogno di qualcosa tipo la BigNum library..ma magari qualcuno conosceva qualcosa di già ottimizzato. grazie

deleted_29
18-01-2011, 17:00
Originariamente inviato da Toxotes
Per lavorare con precisioni così alte penso ci sia bisogno di qualcosa tipo la BigNum library.. :mem:

Per avere un'idea (alla grossa) di cosa significhi 10^50, è circa 10.000 più grande del rapporto tra il diametro di un atomo e quello dell'intero universo.

Forse è un livello di precisione... un pochino esagerato!

Toxotes
18-01-2011, 17:55
molto semplicemente il 1.e-15 o poco più che ho con un double non basta. Almeno penso di aver idenificato questo come problema. La funzione delle nuemerical recipies è un pò strana..sembra che usi un pò bisezione e un pò il metodo di Newton, ora non c'ho dietro il libro e mi sta un pò fatica leggermi tutto il codice. Comunque se conoscete una funzione per il calcolo degli zeri che sapete essere molto precisa vi sarei grato.

P.S.

Per avere un'idea (alla grossa) di cosa significhi 10^50, è circa 10.000 più grande del rapporto tra il diametro di un atomo e quello dell'intero universo.

No scusa ma per fare questi esempi del menga pretendo che tu sia uno studente di fisica :D
Io li trovo simpatici, ma infatti studio fisica :D :D

deleted_29
18-01-2011, 18:00
Originariamente inviato da Toxotes
molto semplicemente il 1.e-15 o poco più che ho con un double non basta. Almeno penso di aver idenificato questo come problema.Francamente dubito, senza sapere nulla di nulla direi "a occhio" stabilità

...Comunque se conoscete una funzione per il calcolo degli zeri che sapete essere molto precisa vi sarei grato...Non vorrei sembrare "saccente", ma... di QUALE funzione?
"Zeri di funzione" non dice un granchè.


P.S.
No scusa ma per fare questi esempi del menga pretendo che tu sia uno studente di fisica :D
Io li trovo simpatici, ma infatti studio fisica :D :D no, non è un esempio del menga, è un esempio (per quanto sia vagamente realistico) sulla base del diametro dell'atomo di elio e il (presunto) diametro dell'universo.
E no, non sono studente di fisica, o meglio l'ho già studiata :zizi:

Per gli zeri invece ho studiato con questo signore (e col suo devastante accento)

C.Broyden (http://tinyurl.com/62wsmhl)

Toxotes
18-01-2011, 18:26
azz...con Broyden in persona?

Comunque per quanto riguarda il "menga" era solo una battuta...penso di comprendere abbastanza bene quanto è 10^50. cerco soluzioni per un equazione trascendente tipo T=ln(F(T)) e quindi cerco lo zero di T-ln(F(T)).

deleted_29
18-01-2011, 21:41
Originariamente inviato da Toxotes
azz...con Broyden in persona?ebbene sì


Comunque per quanto riguarda il "menga" era solo una battuta...penso di comprendere abbastanza bene quanto è 10^50. cerco soluzioni per un equazione trascendente tipo T=ln(F(T)) e quindi cerco lo zero di T-ln(F(T)).
Ma cos'è F?
se metti ad esempio
la somma per i=1...30
i* xi ^4 + gauss (0,9) la faccenda si complica.

l'algoritmo "più adatto" dipende da "cosa" puoi fare sulla funzione. I metodi "analitici" richiedono la derivabilità (in realtà spesso differenziabilità), almeno per intervalli convessi.
se invece hai funzioni "rumorose" i metodi a discesa di gradiente (più o meno "furbi") falliscono miseramente.

Toxotes
18-01-2011, 22:30
la funzione è derivabile essendo una composizione di esponenziali...è molto lunga e non te la sto a riportare ma ci sono diversi termini che si addizionano/sottraggono con vari membri a dividere quindi potrebbe anche esplodere in qualche punto...non lo so così a occhio. Magari domattina faccio qualche conto. La funzione che sto usando per cercare lo zero comunque è questa:



double rtsafe(void (*funcd)(double, double *, double *), double x1, double x2,
double xacc)
{
void nrerror(char error_text[]);
int j;
double df,dx,dxold,f,fh,fl;
double temp,xh,xl,rts;

(*funcd)(x1,&fl,&df);
(*funcd)(x2,&fh,&df);
if ((fl > 0.0 && fh > 0.0) || (fl < 0.0 && fh < 0.0))
nrerror("Root must be bracketed in rtsafe");
if (fl == 0.0) return x1;
if (fh == 0.0) return x2;
if (fl < 0.0) {
xl=x1;
xh=x2;
} else {
xh=x1;
xl=x2;
}
rts=0.5*(x1+x2);
dxold=fabs(x2-x1);
dx=dxold;
(*funcd)(rts,&f,&df);
for (j=1;j<=MAXIT;j++) {
if ((((rts-xh)*df-f)*((rts-xl)*df-f) >= 0.0)
|| (fabs(2.0*f) > fabs(dxold*df))) {
dxold=dx;
dx=0.5*(xh-xl);
rts=xl+dx;
if (xl == rts) return rts;
} else {
dxold=dx;
dx=f/df;
temp=rts;
rts -= dx;
if (temp == rts) return rts;
}
if (fabs(dx) < xacc) return rts;
(*funcd)(rts,&f,&df);
if (f < 0.0)
xl=rts;
else
xh=rts;
}
nrerror("Maximum number of iterations exceeded in rtsafe");
return 0.0;
}


dove in funcd i due puntatori puntano uno la funzione (il primo) e l'altro la sua derivata prima. Non ricordo sinceramente se è delle numerical recipies o dove l'ho pescata...

Loading