Torna indietro   Hardware Upgrade Forum > Software > Programmazione

Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo
Lenovo Legion Go 2 è la nuova handheld PC gaming con processore AMD Ryzen Z2 Extreme (8 core Zen 5/5c, GPU RDNA 3.5 16 CU) e schermo OLED 8,8" 1920x1200 144Hz. È dotata anche di controller rimovibili TrueStrike con joystick Hall effect e una batteria da 74Wh. Rispetto al dispositivo che l'ha preceduta, migliora ergonomia e prestazioni a basse risoluzioni, ma pesa 920g e costa 1.299€ nella configurazione con 32GB RAM/1TB SSD e Z2 Extreme
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti
A re:Invent 2025, AWS mostra un’evoluzione profonda della propria strategia: l’IA diventa una piattaforma di servizi sempre più pronta all’uso, con agenti e modelli preconfigurati che accelerano lo sviluppo, mentre il cloud resta la base imprescindibile per governare dati, complessità e lock-in in uno scenario sempre più orientato all’hybrid cloud
Cos'è la bolla dell'IA e perché se ne parla
Cos'è la bolla dell'IA e perché se ne parla
Si parla molto ultimamente di "bolla dell'intelligenza artificiale", ma non è sempre chiaro perché: l'IA è una tecnologia molto promettente e che ha già cambiato molte cose dentro e fuori le aziende, ma ci sono enormi aspettative che stanno gonfiando a dismisura i valori delle azioni e distorcendo il mercato. Il che, com'è facile intuire, può portare a una ripetizione della "bolla dotcom", e forse anche di quella dei mutui subprime. Vediamo perché
Tutti gli articoli Tutte le news

Vai al Forum
Rispondi
 
Strumenti
Old 06-11-2010, 17:02   #1
_BlackTornado_
Senior Member
 
Iscritto dal: May 2005
Messaggi: 1169
[C++] NaN e inf... Come li evito?

Salve a tutti...
Purtroppo, nella mia niubbagine, torno da voi, perchè mi trovo con un problema che non so risolvere.

Sto facendo un programma che risolve numericamente con Newton-Raphson un particolare sistema di equazioni non lineari.

Si tratta quindi di prendere matrici, fare jacobiani, invertirle e poi moltiplicarle e sottrarle per qualche vettore. Il tutto, iterato per tot volte.

In pratica, già dopo pochi cicli, alcuni valori mi schizzano verso più infinito, altri verso meno infinito.
Dopo 5 cicli mi ritrovo come soluzione inf inf -inf -inf.
Se lo mando avanti per 100 cicli, mi trovo nan nan nan nan.

Ora, nella mia completa niubbaggine, non mi ero mai trovato ad affrontare casi del genere (quando il programma mi ha dato "nan" ho dovuto cercare su google il significato), ed è un comportamento che non sto in alcun modo ricercando (il programma dovrebbe restituire dei numeri).

Mi sono accorto che la funzione che "inverte lo Jacobiano" mi restituisce, in alcuni valori, un "-0" invece che 0. Può essere questo che mi sputtana tutto? Come faccio ad evitarlo?
Un altra possibile causa potrebbe essere che alcuni determinanti che "dovrebbero" venire 0 vengono in realtà un numero molto piccolo, ma non 0.
L'invertiMatrice quindi va a dividere per questi "quasi 0" e ottiene numeri enormi.
Ho provato ad inserire un controllo sul determinante, dicendo di non invertire se il determinante è minore di 0.0001, ma apparentemente non è cambiato niente.

PS: Mathematica risolve lo stesso sistema con Newton-Raphson senza incontrare determinanti uguali a 0, o almeno credo.

PS: Ho dimenticato di dire che sono ragionevolmente sicuro che le varie funzioni "funzionino" in linea di massima, perchè ho fatto numerose prove.
Quando però mi trovo con tanti "0" nella matrice, quando vado a invertire, in questo caso diventano "-0", e il programma "impazzisce".

Questi sono i sottoprogrammi in questione:

Codice:
bool risoluzioneNewtonRaphson (float pEnne[4], float gdl, float tolleranza1, float tolleranza2){
	 int i, j;
	 float funzione[4], Jacobiano[4][4], JacInverso[4][4], prodotto[4], diffSoluzioni[4], pEnnepUno[4];
	 for (i=0; i<5; i++){
		 creaFunzione(pEnne, gdl, funzione);
		 //cout << "funzione" << endl;
		 //stampaVettore(funzione);
		 creaJacobiano(pEnne, Jacobiano);
		 cout << endl << endl << "jacobiano";
		 stampaMatrice(Jacobiano);
         if (invertiMatrice(Jacobiano, JacInverso)==false){
			return false;
            }
         cout << endl << endl <<"JacInverso";
         stampaMatrice(JacInverso);
		 calcolaProdotto(Jacobiano, funzione, prodotto);
		 //cout <<  endl <<"Prodotto" << endl;
		 //stampaVettore(prodotto);
		 sottraiVettori(pEnne, prodotto, pEnnepUno);
		 //cout <<  endl << "pEnnepUno" << endl;
		 //stampaVettore(pEnnepUno);
		 sottraiVettori(pEnnepUno, pEnne, diffSoluzioni);          
		 creaFunzione(pEnnepUno, gdl, funzione);
		 for (j=0; j<4; j++){
			 pEnne[j] = pEnnepUno[j];
			 }
		 if (moduloVettore(diffSoluzioni) <= tolleranza2 && moduloVettore(funzione) <= tolleranza1){
            return true;
            }
		 }
	return false;
	}
	
void creaFunzione(float pEnne[], float gdl, float funzione[4]){
	funzione[0] = l2*cos(gdl) + pEnne[0]*cos(pEnne[1]);
	funzione[1] = l1 + l2*sin(gdl) + pEnne[0]*sin(pEnne[1]);
	funzione[2] = l2*cos(gdl) + (l3l4 - pEnne[0])*cos(pEnne[1]) + pEnne[2];
	funzione[3] = l2*sin(gdl) + (l3l4 - pEnne[0])*sin(pEnne[1]) + pEnne[3] + l6;
	return;
	}
	
void creaJacobiano(float pEnne[], float Jacobiano[4][4]){
	Jacobiano[0][0] = cos(pEnne[1]);
	Jacobiano[1][0] = sin(pEnne[1]);
	Jacobiano[2][0] = -1*cos(pEnne[1]);
	Jacobiano[3][0] = -1*sin(pEnne[1]);
	Jacobiano[0][1] = -1*pEnne[0]*sin(pEnne[1]); 
	Jacobiano[1][1] =  pEnne[0]*cos(pEnne[1]);
	Jacobiano[2][1] = -1*(l3l4 - pEnne[0])*sin(pEnne[1]);
	Jacobiano[3][1] =  (l3l4 - pEnne[0])*cos(pEnne[1]);
	Jacobiano[0][2] = 0;
	Jacobiano[1][2] = 0;
	Jacobiano[2][2] = 1;
	Jacobiano[3][2] = 0;
	Jacobiano[0][3] = 0;
	Jacobiano[1][3] = 0;
	Jacobiano[2][3] = 0;
	Jacobiano[3][3] = 1;
	return;
	}

bool invertiMatrice(float matr[4][4], float inv[4][4]){
     int i, j;
     float matrid[4][4], complAlg[4][4];
     // In questo IF, il determinante non e' zero, perchè con le approssimazioni float e' praticamente impossibile che
     // det venga esattamente 0, ma in genere viene un numero molto piccolo.
     if (det(4, matr)<0.0001){
				cout << "il determinante e':" << det(4, matr) << endl;
                cout << endl << "La matrice non e' invertibile!" << endl;
                return false;
                }
     complAlgebrici(matr, matrid, complAlg);
     calcolaTrasposta(complAlg, inv);
     for(i=0; i<4; i++){
         for(j=0; j<4; j++){
                  inv[i][j]=inv[i][j]/(det(4, matr));
               }
         }
     return true;
     }
     
void complAlgebrici(float matr[4][4], float matrid[4][4], float complAlg[4][4]){
     int i, j;
     for (i=0; i<4; i++){
         for (j=0; j<4; j++){
             riduciMatrice(matr, matrid, i, j);
             if (pd(i-j)==true){
                                complAlg[i][j] = det(4-1, matrid); 
                                }
             else {
                  complAlg[i][j] = -1*det(4-1, matrid); // Attenzione: qui è meglio mettere -1* invece di -det per evitare roba che diventi -0.
                  }
             }
         }
     return;
     }
     
float det(int dim, float matr[4][4]){
      int i,j,k;
      float determinante = 0;
      float matrid[4][4];
      if (dim==1){
              determinante = matr[0][0];
              }
      for (i=0; i<dim && dim>1; i++){
           for (j=0; j<dim; j++){
                for (k=1; k<dim && j!=i; k++){
                     if (j<i){matrid[j][k-1]=matr[j][k];}
                     if (j>i){matrid[j-1][k-1]=matr[j][k];} 
                     }
                  }
                determinante=determinante + pot(i) * matr[i][0] * det(dim-1,matrid); 
           }
      return determinante;
      }
      
int pot(int i){                           
   if(i%2==0){                            
              return 1;                   
			  }                                      
   else {
        return -1;
        }
}

void calcolaTrasposta(float matr[4][4], float trasp[4][4]){
     int i, j;
     for (i=0; i<4; i++){
         for (j=0; j<4; j++){
             trasp[j][i] = matr[i][j];
             }
          }
return;
}

void riduciMatrice(float matr[4][4], float matrid[4][4], int i, int j){
     int r, c, contarighe, contacolonne;
     contarighe = 0;
     contacolonne = 0;
     for (r=0; r<4; r++){        
         for(c=0; c<4; c++){                  
               if (r!=i && c!=j){
                                matrid[contarighe][contacolonne] = matr[r][c];
                                contacolonne++;
                                if (contacolonne == 4-1){
                                                 contarighe ++;
                                                 contacolonne=0;
                                                 }
                                }                                                              
               }
         }
     return;
     }
_BlackTornado_ è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2010, 18:16   #2
Tommo
Senior Member
 
L'Avatar di Tommo
 
Iscritto dal: Feb 2006
Messaggi: 1304
Quote:
Originariamente inviato da _BlackTornado_ Guarda i messaggi
Salve a tutti...
Purtroppo, nella mia niubbagine, torno da voi, perchè mi trovo con un problema che non so risolvere.

Sto facendo un programma che risolve numericamente con Newton-Raphson un particolare sistema di equazioni non lineari.

...
Niubbezza eh

premesso che non so niente del dominio del tuo problema, sicuramente il tuo è un algoritmo che richiede una precisione che i float non possono fornirti, da cui l'errore che si propaga e sballa tutti i risultati.
Infatti non credo proprio che Mathematica utilizzi float normali in calcoli del genere, userà un suo qualche tipo di dato molto ma molto più preciso.

Hai provato ad usare dei double invece dei float?
__________________
*ToMmO*

devlog | twitter
Tommo è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2010, 18:44   #3
_BlackTornado_
Senior Member
 
Iscritto dal: May 2005
Messaggi: 1169
Quote:
Originariamente inviato da Tommo Guarda i messaggi
Niubbezza eh

premesso che non so niente del dominio del tuo problema, sicuramente il tuo è un algoritmo che richiede una precisione che i float non possono fornirti, da cui l'errore che si propaga e sballa tutti i risultati.
Infatti non credo proprio che Mathematica utilizzi float normali in calcoli del genere, userà un suo qualche tipo di dato molto ma molto più preciso.

Hai provato ad usare dei double invece dei float?
Ho provato... L'unica cosa che ottengo è che ci mette di più a passare da "numeroni" a "inf" e poi "nan".

Il mio riferimento a Mathematica era unicamente per dire che non sto chiedendo al programma di dividere qualcosa per 0, altrimenti Mathematica me l'avrebbe detto. Tutto qui.

Non pretendo e non voglio ottenere la precisione di Mathematica, soltanto una serie che converga.
_BlackTornado_ è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2010, 21:43   #4
Tommo
Senior Member
 
L'Avatar di Tommo
 
Iscritto dal: Feb 2006
Messaggi: 1304
Beh, se le iterazioni raddoppiano coi double, allora vuol dire che i numeri in gioco aumentano la loro risoluzione di un'ordine di grandezza ad ogni iterazione;
ad una certa il float fa overflow e diventa inf;
Quindi viene utilizzato come denominatore di una divisione inf/inf, e diventa NaN.
Evidentemente a lungo andare tutti i campi della matrice diventano prima inf e poi NaN.

Direi proprio che devi capire come modificare l'algoritmo per tenere i valori entro range accettabili!
Visto che i numeri sono così enormi, potresti provare a svolgere i calcoli in scala logaritmica?
__________________
*ToMmO*

devlog | twitter
Tommo è offline   Rispondi citando il messaggio o parte di esso
Old 06-11-2010, 23:47   #5
_BlackTornado_
Senior Member
 
Iscritto dal: May 2005
Messaggi: 1169
Quote:
Originariamente inviato da Antonio23 Guarda i messaggi
se in un algoritmo iterativo come newton-raphson i numeri non fanno altro che crescere (l'algoritmo divergere) o è sbagliata la tua implementazione oppure è sbagliata la scelta dei parametri (degli stepsize ecc...)


La prima...

Facevo fare l'inverso dello Jacobiano... E poi nella procedura successiva ci mandavo lo Jacobiano invece che l'inverso :P

Adesso converge... A numeri apparentemente sbagliati, ma questa è un altra storia.

Grazie a tutti.
_BlackTornado_ è offline   Rispondi citando il messaggio o parte di esso
 Rispondi


Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'' per spingere gli handheld gaming PC al massimo Lenovo Legion Go 2: Ryzen Z2 Extreme e OLED 8,8'...
AWS re:Invent 2025: inizia l'era dell'AI-as-a-Service con al centro gli agenti AWS re:Invent 2025: inizia l'era dell'AI-as-a-Se...
Cos'è la bolla dell'IA e perché se ne parla Cos'è la bolla dell'IA e perché se...
BOOX Palma 2 Pro in prova: l'e-reader diventa a colori, e davvero tascabile BOOX Palma 2 Pro in prova: l'e-reader diventa a ...
FRITZ!Repeater 1700 estende la rete super-veloce Wi-Fi 7 FRITZ!Repeater 1700 estende la rete super-veloce...
Cloud sovrano: l'approccio di Broadcom c...
HONOR conferma l'arrivo in Italia di Mag...
La Cina sotto pressione impone maniglie ...
OpenAI integra le app in ChatGPT per tra...
NVIDIA sarebbe pronta a tagliare la prod...
Prezzo minimo storico per iPhone 16 Pro:...
Riot Games scopre una falla nei BIOS che...
Beats in super offerta su Amazon: aurico...
Batterie elettriche, Samsung SDI e Stell...
Clivet presenta Fullness, la pompa di ca...
SpaceX lancerà 167 razzi spaziali...
Yakuza Kiwami 3 e Dark Ties protagonisti...
Privacy a rischio: ecco la VPN che regis...
SpaceX ha annunciato che un satellite St...
ASUSTOR presenta i nuovi NAS Lockerstor ...
Chromium
GPU-Z
OCCT
LibreOffice Portable
Opera One Portable
Opera One 106
CCleaner Portable
CCleaner Standard
Cpu-Z
Driver NVIDIA GeForce 546.65 WHQL
SmartFTP
Trillian
Google Chrome Portable
Google Chrome 120
VirtualBox
Tutti gli articoli Tutte le news Tutti i download

Strumenti

Regole
Non Puoi aprire nuove discussioni
Non Puoi rispondere ai messaggi
Non Puoi allegare file
Non Puoi modificare i tuoi messaggi

Il codice vB è On
Le Faccine sono On
Il codice [IMG] è On
Il codice HTML è Off
Vai al Forum


Tutti gli orari sono GMT +1. Ora sono le: 18:52.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Served by www3v