Newsgroup: it.scienza.fisica
Titolo: ricerca radici di polinomio di grado qualsiasi (anche non intersecante, ma solo tangente, l'asse X)

 
Vorrei un parere comparativo, relativo ai due metodi, delle 
tangenti (Newton) e delle secanti o corde.
In particolare non sono iper-interessato all'efficienza 
pura, chi converge prima e chi no, quanto piuttosto a quale 
ritenete piï¿œ "resiliente" ad andamenti avversi, tipo come 
dicevo sopra, la mera tangenza all'asse X (quindi il non 
potersi avvalere del cambio segno).
 
Si consideri anche il grado elevato a sufficienza da rendere 
parimenti non immediato il calcolo delle derivate esatte 
(pure calcolabili, dato che i polinomi sono noti), 
specialmente nel porle uguali a zero per cercare massimi 
minimi e flessi (nel qual caso il problema ricasca 
ricorsivamente in quello presente).
 
E' vero che usando il metodo delle secanti la convergenza 
non ï¿œ monotï¿œna, sebbene sia comunque garantita anche se la 
funzione nella zona indagata fa le bizze e cambia curvatura 
ed ha anche piï¿œ di una radice ?
 
Se invece nei paraggi non ha nessuna radice, ne trova 
necessariamente una piï¿œ lontana o l'andamento diventa caotico ?
 
grazie di ogni parere
Ciao
CCCP
 
-- 
1) Resistere, resistere, resistere.
2) Se tutti pagano le tasse, le tasse le pagano tutti
Soviet_Mario - (aka Gatto_Vizzato)

 una più lontana o l'andamento diventa caotico ?
 
 
Mario, mi pare che intendi usare i metodi delle secanti e delle tangenti 
*al di fuori* degli scopi per cui sono stati inventati e dei casi in cui 
garantiscono la convergenza.
 
*Entrambi* i metodi garantiscono la convergenza solo se applicati a un 
intervallo chiuso in cui e' certo che vi sia una e una sola radice di 
f=0, e nel quale il prodotto f'*f" non cambi mai di segno. Se queste 
condizioni sono soddisfatte, entrambe le convergenze sono monotone e da 
direzione diversa; per questo si usano entrambi i metodi, per terminare 
quando la differenza fra i due e' inferiore alla precisione cercata. Se 
queste condizioni non sono soddisfatte, entrambi i metodi possono 
benissimo divergere. Tantopiu' se nell'intervallo la funzione fa le 
bizze :-)
 
Non sono certamente adatti a cercare zeri, e tantomeno zeri multipli, in 
un intervallo su cui dell'andamento di f non si sa nulla.
 
 
Visto che sai che f e' un polinomio di grado n, io sfrutterei piuttosto 
questa conoscenza. Fra due zeri reali di f c'e' sicuramente uno zero di 
f'; fra due zeri di f' c'e' sicuramente uno zero di f"; fra due zeri di 
f^m c'e sicuramente uno zero di f^m+1.
 
Immagino che n sia al piu' dell'ordine del centinaio, altrimenti i 
problemi cui vai incontro sono ben altri, di rappresentazione numerica. 
Derivare 300 volte un polinomio di grado 300 e' una banalita': 
sopratutto visto che delle derivate qui interessano solo gli zeri, e 
quindi si puo' normalizzare a 1 il coefficente del termine di grado 
massimo di ogni polinomio derivata. Deriva f n-1 volte, fino a 
determinare una retta, e salva tutti i coefficienti di tutte le derivate 
in una matrice n x n+1.
 
Ora determina gli estremi inferiore e superiore di un intervallo 
[lower,upper] d'interesse: se la conoscenza del problema reale non ti e' 
d'aiuto, puoi usare il teorema di Cauchy: tutti gli zeri reali di un 
polinomio
 
    a_0 + a_1 x + a_2 x^2 ... + a_n x^n
 
sono compresi nell'intervallo [-a, a] con
 
    a = 1 + max (| a_i/a_n |)    ,   i=/=n.
 
 
Parti dalla derivata n-1esima, trova il suo zero x_0 (c'e' di sicuro, 
altrimenti il polinomio non e' di grado n ma inferiore), e verifica se 
cade all'inteno di [lower,upper]. Se cade al di fuori, mantieni un solo 
intervallo per passare alla derivata n-2esima. Se cade invece 
al'interno, dividi [upper,lower] nei due intervalli [lower,x_0] e 
[x_0,upper]. Per ogni sottointervallo, se la f^n-2 cambia di segno fra 
gli estremi (o E' zero ad uno degli estremi), li' c'e' uno zero, e *uno 
solo*.
 
Per trovarlo, visto che privilegi la robustezza alla velocita', puoi 
usare il metodo della bisezione, che e' il piu' robusto che si conosca, 
indipendentemente dall'andamento delle derivate: la convergenza e' 
lineare e non superlineare (ma anche il metodo delle tangenti e' lineare 
se la radice e' multipla), ma con funzioni rapide da calcolare come i 
polinomi non sara' certo questo un problema (suggerimento: per calcolare 
i valori dei polinomi usare l'algoritmo di Horner, o almeno conservare 
x^n per il calcolo di x^(n+1), il che rispetto ad Horner si limita a 
raddoppiare il tempo necessario).
 
Se invece la f^n-2 non cambia di segno, li' semplicemente un suo zero 
non c'e', e puoi passare avanti.
 
Ad ogni passo trovi gli zeri reali di f^(n-m) compresi fra lower e 
upper, e li usi per definire gli intervalli in cui cercherai gli zeri 
della derivata precedente, essendo sicuro che in ogni intervallo ce n'e' 
al piu' uno; fino ad arrivare agli zeri della derivata di ordine zero, 
ossia del polinomio di partenza.
 
 
 
-- 
TRu-TS
Buon vento e cieli sereni

 una più lontana o l'andamento diventa caotico ?
 
Per i polinomi ci sono metodi specifici: il metodo di Bairstow permette 
di isolare dei fattori di secondo grado e di trovare gli zeri a due per 
volta:
 
http://www.vialattea.net/esperti/mat/bairstow/bairstow.htm
 
http://it.wikipedia.org/wiki/Algoritmo_di_Bairstow
 
 
Qui lo si confronta con il metodo quoziente-Differenza:
www.matematicamente.it/staticfiles/approfondimenti/approfondimenti/Equazioni_algebriche.pdf
 
 
-- 
"Oggi la scienza ha scoperto come asportare il cuore di un uomo [...].
E la propaganda è riuscita in più occasioni ad asportare la mente di 
intere nazioni." (Brian Fawcett, Cambogia)


 
 
-- 



 
Allora, ora mi ristudio tutto per bene, e rimando eventuali 
altri commenti a dopo, ma devo innanzitutto ringraziarti per 
la disponibilità e la spiegazione dettagliata.
P.S. non so se alla fine lo farò, perché in fondo è uno 
sfizio, e non so manco se e quanto ti possa interessare 
(presumo una epsilon piccola a piacere), ma quando/se farò 
funzionare al meglio questo programma "didattico" di 
risoluzione di multi equilibri, vorrei vedere se per caso su 
"Chimica nella Scuola" accettano software oltre ad articoli 
di solo testo, e se si, ovviamente ti citerei volentieri 
come coautore e consulente matematico.
Ma non sono sicurissimo di perdere interesse (già scarso) a 
questo aspetto. Tutto sommato vorrei solo uno strumento di 
risoluzione simultanea, per valutare rapidamente in vari 
contesti una miriade di formule approssimate che usiamo per 
trattare gli equilibri.
ciao


 raddoppiare il tempo necessario).
 
Sin al fatto di generare iterativamente la potenza pian 
piano c'ero arrivato per intuizione, ma non ad inglobare la 
costante del grado inferiore ad ogni step ! Che figata ... 
grazie della segnalazione !
Ora provo a comprendere meglio tutti i dettagli con un 
approccio BOTTOM-UP.
Riciao ed ad majora
CCCP
CUT


T'interessano le radici reali o quelle complesse? O entrambe? Ti 
interessa la molteplicità?
 
In buona sostanza il metodo delle secanti e delle tangenti sono dei 
Newton modificati, nei quali sostituisci la derivata della funzione con 
una sua approssimazione.
Trattandosi di polinomi, ovvero di funzioni 'lisce', piene di buone 
qualita', e curandoti troppo di velocità di convergenza, anche se 
consideri gradi elevati, tutto sommato un metodo vale l'altro, visto che 
difficilmente sarai in presenza di oscillazioni tali da costituire un 
problema per la convergenza.
 
In ogni caso esistono metodi specializzati per determinare zeri di 
polinomi, ma sono praticamente esercizi di stile...
 
 
Il 10/12/2012 18:01, Soviet_Mario ha scritto:>


  > Vorrei un parere comparativo, relativo ai due metodi, delle tangenti
 
 


>
Scusate, sempre sulla questione dei polinomi, avrei ora un 
dubbio diverso.
 
Ripeto en passant la loro genesi e quindi le loro 
peculiarità (tra i tanti polinomi) : Si possono tutti 
descrivere come
 
(a1-n1X)^n1*(a2-n2X)^n2*...*(az-nzX)^nz = K*  (segue)...
(b1-m1X)^m1*(b2-m2X)^m2*...*(bt-mtX)^mt
 
dove,
a1 a2 a3 ... az sono positivi (reali)
b1 b2 b3 ... bt sono positivi (reali)
n1 n2 n3 ... nz sono naturali
m1 m2 m3 ... mz sono naturali
K è positivo (reale)
 
vale inoltre, sempre, che ogni monomio è strettamente 
maggiore di zero, per cui il primo membro ed il secondo sono 
sempre positivi.
 
dopo averlo ristrutturarlo come
 
N * (a1/n1 - X)^n1*(a2/n2 - X)^n2*...*(az/nz - X)^nz = K * D 
* (b1/m1 - X)^m1*(b2/m2 - X)^m2*...*(bt/mt - X)^mt
 
dove N = n1^n1 * n2^n2 * ... * nz^nz
ed D = m1^m1 * m2^m2 * ... * mt^mt
 
inglobando le costanti, diventa ancora
 
(A1 - X)^n1*(A2 - X)^n2*...*(Az - X)^nz -
- K# * (B1 - X)^m1*(B2 - X)^m2*...*(Bt - X)^mt = 0
 
spostando i due pezzi al primo membro ed ottenendo 
un'equazione (di grado anche elevato)
 
Ora, in un RECIPIENTE, si versano sostanze capaci di 
mettersi in multiequilibrio.
 
Ciascuna REAZIONE sarà caratterizzata dal suo bravo 
polinomio, di grado diverso, con esponenti e costanti 
iniziali diverse/eguali in parte e per caso.
 
Abbiamo quindi un generico sistema (fisico) rappresentato da
un certo numero enne di equazioni polinomiali, di grado 
qualsiasi, tante quante le enne reazioni (non tante quante i 
composti). Ogni polinomiale è in una variabile distinta. Per 
cui enne variabili ed enne equazioni (non lineari).
 
Ebbene, non so se un tale sistema debba avere una sola 
soluzione (ne avevamo discusso tempo fa con Tetis, che 
riteneva che potessero esisterne anche più d'una).
Per soluzione intendo una "ennupla" di valori delle 
incognite tali da soddisfare tutte le polinomiali.
 
Ma la cosa che mi chiedevo è se esiste qualche ragione 
matematica, qualche teorema che so, che dimostra che quel 
sistema DEVE NECESSARIAMENTE possedere ALMENO una ennupla di 
soluzioni reali e di significato fisico.
La ragione FISICA esiste : qualunque mescolanza raggiunge, 
dopo un tempo sufficiente ed eventualmente oscillazioni 
smorzate per essere generali, sempre uno stato di equilibrio.
Ma matematicamente perché è così ? Perché data la 
peculiarità di quei polinomi, che sono non lineari, si deve 
sempre poter avere una ennupla reale di soluzioni, quando 
invece ho letto che NON PER FORZA i sistemi non lineari 
garantiscono una soluzione anche quando sono correttamente 
dimensionati (tot incognite, tot equazioni) ?
 
Se poi qualcuno, ma non penso, se no Tetis lo avrebbe già 
saputo lui, pensa di poter dimostrare che debba sempre 
esistere una sola ennupla, mi interessa pure quello.
Ma già mi accontento di sapere come mai ce ne debba essere 
almeno una.
Ciao
(buon Natale)
CCCP
 
 
 
ciao


 Ciao (buon Natale)
 
Grazie degli auguri e buon anno nuovo, se mi pubblicano in tempo ;-)


 formule approssimate che usiamo per trattare gli equilibri.
 
Dunque, in calce incollo la routine (fortran 95, testata con gcc f95 su 
Linux), completa di routine di servizio e programma di test, di cui ti 
ho parlato nel post precedente (non so quale dei due arrivera' prima :-)
 
Dato che spesso copiaincollare codice risulta in programmi 
incompilabili, ho messo il file anche qui:
http://trusso.freeshell.org/SovietMario/DoubleZeriRealiPolinomiReali.f
 
 
 
Il modo migliore di capire l'algoritmo (che avevo cercato di descriverti 
senza troppa chiarezza) e' di leggerla.
 
Come dicevo, la routine funziona egregiamente per trovare zeri singoli e 
distinti di polinomi "onesti" :-), anche tirando un po' il loro range di 
variazione. Per esempio, calcolando il polinomio
 
(x-.01)*(x-1)*(x-7.3)*(x-18)*(x-100)*(x-10000)*(x-568777)*(x^4+5)
 
che ha ovviamente 7 radici reali e 4 complesse, e si espande come (non 
lo faccio a mano, uso maXima)
 
1000*x^11-578903310*x^10+5760878110833*x^9-720035853390518*x^8+15866453941479473*x^7-
90040929443886828*x^6+75664925530631965*x^5-4347552244952590*x^4+79332269707372365*x^3-
450204632746851390*x^2+378180605700389000*x-3736864890000000
 
dando in pasto al programma il grado, 11, e poi i coefficienti (in 
ordine canonico):
 
1000 -578903310 5760878110833 -720035853390518 15866453941479473 
-90040929443886828  +75664925530631965  -4347552244952590 
79332269707372365 -450204632746851390 378180605700389000 -3736864890000000
 
vengono trovate correttamente le 7 radici reali.
 
 
Nel caso di zeri multipli, anche questo algoritmo (come tutti) da' dei 
problemi: la ragione sta principalmente nel fatto che gli zeri multipli 
cadono ad un estremo dell'intervallo, che e' stato determinato nel passo 
precedente con precisione macchina (16 cifre decimali, nel nostro caso), 
dove la derivata era molto prossima allo zero ma non necessariamente 
proprio zero. Non sapendo a priori cosa, *nello specifico problema*, 
possa essere considerato "sufficientemente vicino" allo zero, la routine 
di bisezione agli estremi testa se il polinomio e' esattamente eguale a 
zero; se non lo e', non lo considera tale. E, a seconda del segno che il 
polinomio assume in quel punto e all'altro estremo dell'intervallo, puo' 
trovare per bisezione un altro zero molto vicino, o non trovarne alcuno.
 
Un altro motivo che puo' far mancare uno zero di tangenza e' 
l'arrotondamento effettuato nel calcolo del polinomio: a seconda dei 
casi, uno zero multiplo puo' non essere trovato per niente, o essere 
determinato come 2 o piu' zeri distinti, anche se molto vicini. Inoltre, 
nella costruzione stessa del polinomio a partire dall'espressione
 
      (x-x1)^n1 * (x-x2)^n2...   ...(x-xm)^nm
 
si verificano arrotondamenti, per cui i coefficienti del polinomio che 
poi si da' in pasto alla routine non sono quelli voluti, ma coefficienti 
di *un altro* polinomio, che magari gli zeri cercati proprio non li ha.
 
Nei casi piu' semplici, in cui il calcolo del polinomio riesce a dare un 
risultato esatto, gli zeri vengono trovati, e con la corretta 
molteplicita': per esempio, partendo da
 
    (x-1.5)^10
 
cioe'
 
1024*x^10-15360*x^9+103680*x^8-414720*x^7+1088640*x^6-1959552*x^5+2449440*x^4-2099520*x^3+
1180980*x^2-393660*x+59049
 
dando in input i coefficienti
 
1024 -15360 +103680 -414720 +1088640 -1959552 +2449440 -2099520 +1180980 
-393660 +59049
 
si trovano proprio 15 zeri pari a 1.5000000;
 
 
ma in altri casi, dove gli arrotondamenti acquistano importanza, gli 
zeri vengono trovati con molteplicita' difettosa o non trovati del 
tutto. Es:
 
(x-1)^4*(x-0.07)^4*(x^2+3)
cioe'
100000000*x^10-428000000*x^9+1014940000*x^8-1863897200*x^7+2375011201*x^6-1780284404*x^5
+694076809*x^4-121925216*x^3+10512019*x^2-440412*x+7203
grado 10 e coefficienti
100000000 -428000000 +1014940000 -1863897200 +2375011201 -1780284404 
+694076809 -121925216 +10512019 -440412 +7203
 
gli zeri 1 e 0.07 vengono determinati, ma con molteplicita' 2 anziche' 4;
 
sostituendo 0.07 con 0.007,
 
(x-1)^4*(x-0.007)^4*(x^2+3)
ciooe'
1000000000000*x^10-4028000000000*x^9+9112294000000*x^8-16253177372000*x^7+
19450651490401*x^6-12536716357604*x^5+3341607973609*x^4-87554106416*x^3+898509619*x^2-4144812*x
+7203
grado 10 e coefficienti
1000000000000 -4028000000000  9112294000000 -16253177372000 
19450651490401 -12536716357604 3341607973609 -87554106416 898509619 
-4144812 7203
 
gli zeri a 1 non vengono piu' trovati.
 
 
Come dicevo nell'altro post, non credo che i casi che tratti tu siano 
cosi' patologici, per cui questa routine dovrebbe esserti utile e 
sufficiente: in ogni caso, per vedere cosa dovresti aspettarti, ti 
conviene tirar fuori per prima cosa il polinomio e plottarlo.
 
Se invece effettivamente lo sono, dovresti fornirmi qualche caso reale 
su cui ragionare.
 
Ciao e buon anno
 
 
 
!           (fixed width characters are better)
!23456789 123456789 123456789 123456789 123456789 123456789 123456789 12
 
       RECURSIVE Subroutine findrealzeroes(N,coeff, Nzeroes,zeroes)
C     note: a_0 = coeff(0) is known term,
C           a_i = coeff(i) is coefficient of x^i
 
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
C     ( yes, I'm a VERY old Fortran programmer :-)
 
       dimension coeff(0:N), zeroes(1:N)
       double precision,dimension(:),allocatable :: endpoints, dcoeff
       logical zerofound
 
       if (coeff(N).eq.0.) STOP "*** Polynomial is NOT of degree N ***"
       print *, "**** degree: ",N,"   ****"
 
       Cauchy = CauchyRadius(N,coeff)
       print*, "Cauchy bounds: ",-Cauchy,Cauchy
 
       if (N.eq.1) then
C      straight line with non zero a_1
        Nzeroes = 1
        zeroes(1) = - coeff(0)/coeff(1)
 
       else
C      allocate space for derivate polynomial and intervals
        allocate ( endpoints(0:N), dcoeff(0:N-1) )
 
C      derive polynomial and normalize derivate polynomial
C      so that max degree coeffincent remains the same
        do i=0,N-1
         dcoeff(i) = ((i+1) * coeff(i+1)) / N
        enddo
 
        print *, "Normalized derivate:"
        print *, (dcoeff(i), i=N-1,0,-1)
 
C      initialize interval endpoints to -Cauchy,Cauchy,...,Cauchy.
        endpoints(0) = -Cauchy
        do i=1,N
         endpoints(i)=Cauchy
        end do
 
C      RECURSIVELY find zeroes of derivate polynomial
 
        call findrealzeroes(N-1,dcoeff, NDrealzeroes,endpoints(1) )
 
        Nintervals = NDrealzeroes + 1
C      here endpoints (0:NDrealzeroes+1) contains
C      -Cauchy, 1st zero, 2nd zero ... last zero, Cauchy. (ordered)
 
        print *, Nintervals," intervals endpoints, and values there:"
        print *, (endpoints(i), i=0,Nintervals)
        print *, (poly(N,coeff,endpoints(i)), i=0,Nintervals)
 
C      find *at most one* zero for each interval:
        Nzeroes = 0
        do i = 1, Nintervals
         call bisect(N,coeff,endpoints(i-1),endpoints(i),
      $                                      zerofound,foundzero)
         if (zerofound) then
          Nzeroes = Nzeroes + 1
          zeroes(Nzeroes) = foundzero
         endif
        end do
 
C      cleanup:
        deallocate ( endpoints, dcoeff )
       endif
 
       print *, "Degree ",N," real zeroes found, and relative values:"
       print *, (zeroes(i), i=1,Nzeroes)
       print *, (poly(N,coeff,zeroes(i)), i=1,Nzeroes)
       return
       end
 
 
 
       double precision function CauchyRadius(N,a)
C     note: a_0 = a(0) is known term,
C           a_i = a(i) is coefficient of x^i
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
       dimension a(0:N)
       CauchyRadius = 1.
       do i=0,N-1
        CauchyRadius = max (CauchyRadius, abs(a(i)/a(N))+1.)
       end do
       return
       end
 
 
 
       subroutine bisect(N,coeff,xinit,xend,  zerofound,foundzero)
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
 
       dimension coeff(0:N)
       logical zerofound, nearlysame
C     simple bisection method: other methods
C     would be faster, but in this case who cares...
 
       zerofound = .false.
 
       x1 = xinit
       x2 = xend
       poly1 = poly(N,coeff,x1)
       poly2 = poly(N,coeff,x2)
 
C      print *, "entered bisect: N = ",N,
C     $     " x1 = ",x1,poly1," x2 = ",x2,poly2
 
       if (poly1*poly2.gt.0.) return
 
       if(poly1.eq.0. .and. poly2.eq.0.)then
        zerofound = .true.
        foundzero = x1
        return
       endif
 
       if(poly1.eq.0.)then
        zerofound = .true.
        foundzero = x1
        return
       endif
 
       if(poly2.eq.0.)then
        zerofound = .true.
        foundzero = x2
        return
       endif
 
       do while (.not. nearlysame(x1,x2))
       xm = (x1+x2)/2.
       polym = poly(N,coeff,xm)
        if (polym.eq.0.) then
         zerofound = .true.
         foundzero = xm
         return
        else if (poly1*polym.gt.0.) then
         x1 = xm
         poly1 = polym
        else
         x2 = xm
         poly2 = polym
        endif
       end do
 
       zerofound = .true.
       foundzero = xm
       return
       end
 
 
 
       double precision function poly(N,coeff,x)
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
       dimension coeff(0:N)
 
       poly = coeff(0)
       xpower = 1.
       do i = 1,N
        xpower = xpower * x
        poly = poly + coeff(i)*xpower
       end do
 
       return
       end
 
 
       logical function nearlysame(x1,x2)
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
 
       xm = x1 + (x2-x1)/2.
C     this is needed to avoid a too-optimizing compiler computing
C          x1 - (x1 + (x2-x1)/2.)   as
C          x1 - x1 + (x2-x1)/2.,    i.e. (x2-x1)/2.     ;-)
 
       nearlysame = ((x1-xm).eq.0. .or. (x2-xm).eq.0.)
 
       return
       end
 
 
 
       program testfindrealzeroes
       implicit double precision (a-h,o-z)
       implicit integer (i-n)
 
       parameter (Nmax=100)
       dimension coeff(0:Nmax), zeroes(1:Nmax)
 
       logical EOF /.false./
 
       do while (.not.EOF)
        print *, "--------------------------------------------------"
        print *, "enter degree "
        READ (*, *, IOSTAT=IST) N
        EOF = IST.LT.0
        if(EOF) STOP "bye"
        if (N.gt.Nmax) then
         print *, "max degree is ",Nmax,
      $                ". Enlarge ad recompile if needed"
         STOP
        endif
        if (N.le.0) then
         STOP "degree should be positive"
        endif
        print *, "enter ", N+1, " polynomial coefficents a_n...a0:"
        READ (*, *, IOSTAT=IST) (coeff(i), i=N,0,-1)
        EOF = IST.LT.0
 
        IF (.NOT.EOF) THEN
 
         print *, "polynomial coefficients:"
         print *, (coeff(i), i=N,0,-1)
 
         call findrealzeroes(N,coeff, Nzeroes,zeroes)
 
         print *, "found zeroes, and value of polynomial there:"
         print *, (zeroes(i), i=1,Nzeroes )
         print *, (poly(N,coeff,zeroes(i)), i=1,Nzeroes)
 
        ENDIF
       end do
       STOP "bye"
       end
 
!23456789 123456789 123456789 123456789 123456789 123456789 123456789 12


 formule approssimate che usiamo per trattare gli equilibri.
 
Ma allora ti chiederei di fare qualche prova con la routine che ti mando 
a parte, tanto per verificare di non esserti fasciato la testa per 
niente... se poi invece effettivamente P(x) e' molto malcondizionato, ne 
riparliamo.
 
Ciao


 tangenza ha di solito un ben preciso significato fisico.
 
no, me la sono ammaccata, ma ho tamponato, prima di 
ipotizzarla. Oddio la bisezione mi aveva causato degli stack 
esauriti quando usavo la ricorsione, ma poi ho lavorato e ho 
tramutato una semplicissima sintassi ricorsiva in una 
complicata e macchinosa sintassi iterativa, che però usava 
solo poca memoria.
In particolare la ricorsiva consumava l'integrale delle 
potenze di due, la iterativa, solo l'ultima potenza di due
 
Per dire, al 5 stadio di profondità
Ricorsiva
2^0 + 2^1 + 2^2 + 2^3 + 2^4 + 2^5 = 2^6 - 1 = 63
Iterativa
2^5 = 32.
Praticamente consuma la metà di memoria (di solo 
tracciamento, senza contare le variabili locali). Ed è anche 
più veloce.
Ma cmq sia, ho scoperto una cosa sgradevole che ti racconto 
dopo ... anzi subito.
 
 
Ebbene, ho cambiato completamente strategia e non ricerco 
più nemmeno le radici del polinomio.
Perché mi sono accorto che in un sistema non lineare, non 
saprei cosa farmene delle soluzioni.
 
Mi spiego meglio, oltre alle VARIABILI, uno o più, al limite 
tutti i termini COSTANTI di ciascun polinomio possono 
essere, variazionalmente, ad ogni iterazione, modificati 
dagli altri polinomi. Quindi le soluzioni singole non 
rappresentano per forza soluzioni del sistema nel suo complesso.
Ed è vero che le soluzioni FINALI, a convergenza avvenuta, 
di ogni polinomio, non rappresentano soluzioni delle 
rispettive formulazioni iniziali (perché tutte le costanti 
sono state variate ad ogni iterazione).
 
Provo a rispiegare questo punto.
Avendo scoperto che per polinomi di grado superiore non 
esistono procedure deterministiche di previsione delle 
soluzioni (come quelle dell'algebra lineare stile Gauss 
Jordan che mi aveva spiegato Elio un po' di tempo fa), 
allora avevo implicitamente puntato su una procedura 
evolutiva, variazionale.
E l'effetto collaterale di ciò è che ciascun polinomio, 
anche se non varia struttura formale, pure varia una o più 
d'una o tutte le costanti, che si coevolvono insieme.
 
Quindi la ricerca delle soluzioni esatte di ognuno 
singolarmente l'ho abbandonata : ho fatto delle prove con 
polinomi generati da radici note, e queste soluzioni non 
soddisfavano il sistema completo, ma solo il padre della 
soluzione.
 
A me invece interessava risolvere il sistema.
 
 
Ho optato per una soluzione ispirata dalla fisica 
sottostante : dai concetti di compensazione degli scarti 
dall'equilibrio, e la rispettiva proporzionalità al
Logaritmo del rapporto tra il quozione attuale di reazione e 
il valore della sua costante di equilibrio.
Questi valori di  Ln(Q_r / K_eq)  rappresentano differenze 
di energia libera. Ebbene io ho ordinato la priorità di ogni 
equazione in maniera proporzionale al suo scartamento, di 
modo che la sua richiesta di compensazione avesse priorità 
proporzionale. Ho anche rinormalizzato i pesi, in modo che 
tutto ciò diventasse adimensionale, diciamo.
 
Bene, converge tutto, fa qualche bizza giusto all'inizio, 
con un po' di oscillazioni, un paio, poi converge tutto.
E' algoritmicamente lento, nel senso che occorre qualche 
migliaio di iterazioni (Che però sono molto rapide, perché 
ogni computazione è il computo di una formula analitica e 
non più una ricerca a sua volta, né Newton Raphson né 
bisezione, niente : esegue il calcolo del polinomio come 
espressione unica di costanti, il valore di partenza e la 
variazione stimata).
Quindi normalmente conti sino a dieci, e visualizzazioen 
grafica inclusa, completi diciamo 5000 iterazioni con già 
notevole convergenza.
 
Cmq la nostra discussione mi è servita molto, anche per 
superare un impasse psicologica.
Mi leggerò il resto della risposta con calma, perché al 
momento ho imboccato una strada diversa di ricerca multipla 
contemporanea.
Credo che l'intuizione di tipo "fisico" abbia consentito di 
cercare le soluzioni nella loro direzione naturale, ossia 
consente di sfruttare il fatto che ciascuna equazione in 
realtà sa sempre dove vuole andare, e non deve cercare a 
caso. Sa di essere troppa o troppo poca, e anche stimare 
comparativamente di quanto.
A risentirci ...
A (s)proposito ... ti ho anche cercato su feisbuk, ma forse 
sono stato invadente. Se è così, mi scuso, è stata una cosa 
impulsiva, ma non mi pare che si possa ritirare una 
richiesta. Ormai è nelle tue mani.
Ciao e grazie delle consulenze e della pazienza come al solito
SOVIET

che figata, ottima considerazione.



 Ciao


 stimare comparativamente di quanto.
 
Potenza del secondo principio! :-)


 Potenza del secondo principio! :-)
 
eh he he, nel caso del SW conoscenza ma implementazione 
granulare insufficientemente fina.
La natura invece che lo conosce e implementa meglio, non fa 
quelle 2 o 3 oscillazioni che a volte visualizzo io nei 
grafici ... non che ci perda il sonno.
 
ciao
CCCP


Soviet_Mario ha scritto:
 > Ebbene, ho cambiato completamente strategia e non ricerco
 > piï¿œ nemmeno le radici del polinomio.
 > Perchï¿œ mi sono accorto che in un sistema non lineare, non
 > saprei cosa farmene delle soluzioni.
Ma bravo! Dopo aver messo in movimento un po' di cervelli per trovare
la soluzione, ora ci dici che non sai che fartene!
BTW, io mi ero interessato al problema da un punto di vista del tutto
diverso da quello di Tommaso.
Forse continuerï¿œ a pensarci perchï¿œ mi pare interessante come puro
problema matematico. Vuol dire che non ti farï¿œ sapere se ci cavo
qualcosa :-)
 
 > Mi spiego meglio,
 > ...
 > Provo a rispiegare questo punto.
 > ...
Spiacente, ma questo vecchietto semirimbambito non ha capito una
mazza.
Non potresti partire da zero, spiegando *in modo preciso* il problema
chimico-fisico che hai?
E magari scrivendo le equazioni giuste?
Chissï¿œ che non si riesca a trovare un approccio che funziona...
 
Ti voglio raccontare una storia di oltre 60 anni fa.
A quel tempo gli studenti di fisica dovevano sostenere tre esami di
materia chimica:
- chimica generale con elementi di orgnaica al primo anno
- stechiometria e preparazioni chimiche al secondo
- chimica fisica al terzo.
(Poi col passare del tempo le richieste di chimica per gli studenti di
fisica si sono progressivamente smagrite, fino a svanire del tutto...)
La storia riguarda il secondo esame, che aveva una parte teorica e una
di laboratorio.
 
Su quella di lab. meglio stendere un velo pietoso: non ci imparai
niente. Mi ricordo solo un famigerato provettone, dove si doveva
mettere MnO2 da scaldare alla fiamma per preparare ossigeno.
Ci veniva detto di fare attenzione, perchï¿œ facilmente il provettone si
poteva rompere, e in quel caso avremmo dovuto ripagarlo :-(
Cosa che mi capitï¿œ puntualmente, e mi costï¿œ (credo) 200 lire.
Per darti un'idea, con quella somma si compravano quasi due litri di
benzina.
 
Ma passiamo alla parte teorica. C'era uno scritto, in cui si dovevano
risolvere problemi relativi a equilibri piï¿œ o meno complicati.
Gli esempi conosciuti facevano uso di approssimazioni che io non
riuscivo a capire (prob. erano giustificate da conoscenze che un
chimico aveva sulla punta delle dita, ma un misero studente assai
meno...).
Per cui decisi di adottare una strategia differente: scrivere le
equazioni esatte (s'intende, nell'ambito delle ipotesi note o
suggerite).
Poi guardare quelle equazioni e cercare le appross. migliori per darne
una soluzione accettabile; per es. trascurando alcuni termini (si
trattava sempre di equazioni algebriche) che apparivano piccoli se la
soluzione cercata stava in un certo intervallo, ecc.
Debbo dire come titolo di merito per il professore (era Liberti, non
so se sia conosciuto) che rimase cosï¿œ impressionato dal mio approccio
che mi gratificï¿œ di un bel 30 e lode.
 
Hai capito la morale della storia? :-)
Se non l'hai capita, te la spiego un'altra volta ;-)
-- 
Elio Fabri

 Se non l'hai capita, te la spiego un'altra volta ;-)
 
Si spiega spiega ... E credimi, anche x Tommaso, mi 
rincresce assai di avere chiesto dei lumi su una cosa che 
non avevo neppure sospettato che alla fine non mi sarebbe 
potuta servire.
Mi sono fissato solo sulla "X" dei polinomi, sulla 
autocompensazione, senza però notare che anche le parti 
costanti non erano vere costanti, e che quindi era assurdo 
investire tanto in soluzioni esatte che sarebbero state da 
buttare al ciclo successivo, quando ALTRE equazioni 
avrebbero scompigliato LE COSTANTI di quelle risolte 
separatamente.
Inizialmente pensavo questo : ogni polinomio mi da le sue 
radici, e mi basterà fare un'intersezione. Ma poi mi pare di 
avere capito che non sarebbe stato così, e che 
quell'intersezione sarebbe quasi certamente stata vuota.
Perché in realtà le costanti erano solo valori MOMENTANEI, 
ed il legame tra quei polinomi era ancora più profondo del 
mero "matematicamente" metterli a sistema : era infatti tale 
che se l'intersezione era vuota, essi avrebbero insieme 
smosso tutte le costanti sino a trovare uno (e uno solo ? 
Questo lo chiedo ora) stato che portasse ad intersezione non 
più vuota tra le soluzioni.
Però l'ho capito solo dopo. Se avessi sospettato che era 
così da principio, avrei almeno spiegato il problema fisico 
... ma non ho sospettato. Ahmen !
Ciao
cCCP


 sospettato. Ahmen !
 
8-(



 
 
-- 


 piacere ciao CCCP
 
Ancora una cosa, a proposito di metodi "approssimati" o "deterministici": 
anche per i sistemi lineari non è detto che i cosiddetti metodi 
deterministici siano i migliori, più efficienti o più precisi; nei metodi 
di eliminazione, per esempio, ci può essere un accumulo di errori che 
porta a soluzioni in effetti non corrette, anche se in teoria il metodo è 
assolutamente preciso; nei metodi iterativi, al contrario, se ben 
strutturati, gli errori di approssimazione vengono "tirati giù" al 
passaggio successivo, per cui sovente vengono preferiti ai vari Gauss ecc.
Di Cramer non parliamone nemmeno, visto che la sua complessità esplode 
fattorialmente (in realtà è un metodo che ha un'importanza solo teorica).
Ciao


 Ciao
