IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Java Discussion :

NaN erreur : Probleme à 1 million d'euros - ou presque


Sujet :

Langage Java

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 5
    Points : 6
    Points
    6
    Par défaut NaN erreur : Probleme à 1 million d'euros - ou presque
    Bonjour,

    Voila je suis physicien, ca fait 4 mois que je me suis mis au Java (car ce que je fait, fait parti d'un logiciel plus gros deja en java), pour faire un programme pour traiter des données en Génétique.

    En résumé, mon programme prend une matrice de distance de n points entre eux (n*n) et grace à celle-ci il place ces n points dans n-1 dimensions.
    Mathématiquement la méthode de reconstruction marche y'a pas de problème. Mais qd je met ça dans l'ordi ben ca plante, j'ai une erreur NaN.

    J'ai fait un algo de test (ci-dessous), ou je tire alétoirement une matrice (n points dans m dimensions), je calcule les distances entre les points, et je lance mon algo pour retrouver une nouvelle matrice position.
    Et j'ai presque à chaque fois (ca depend de la grandeur de n) un NaN. Le NaN est du au calcul de racine carrée d'un nombre négatif. Le probleme c'est que je ne devrais jamais avoir de nombre négatif dans cette racine ! (si on regarde le cote mathématique)

    Y'a un truc bizarre qui se passe, peut etre est-ce du a des erreur de calcul typique de java, un truc que je sais pas car je debutes. Ca fait un mois que je suis dessus, et ca m'enerve car l'algo en lui meme est simple, mais ça donne cette %è3$** d'erreur !!!
    En un mot : Heeelllppppppp .....

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
     
    class geotest
    {
    	//  n = nombre de points
    	//  m = dimension de l'espace
    	static int n =100;
    	static int m = n -1;
     
    	// Matrice des positions initiales
    	public static double[][] positionInit = new double[n][m];
    	// Matrice des positions reconstruites par l'algorithme
    	public static double[][] position = new double[n][m];
    	// Matrice des distances
    	public static double[][] distance = new double[n][n];
    	// petite methode pour calculer un carre
    	static double SQR(double x) { return x * x; }
     
    	// Calcul de la distance euclidienne pour la matrice de position
    	static double dist(double[][] position, int a, int b)
    	{
    		double sum = 0.0;
    		for (int i = 0; i < m; i++)
    		{
    			sum = sum + SQR(position[a][i] - position[b][i]);
    		}
    		return Math.sqrt(sum);
    	}
     
     
    	public static void main(String[] args)
    	{
    		// On crée une matrice triangulaire aléatoire
    		for (int i = 0; i < n; i++)
    		{
    			for (int j = 0; j < i; j++) positionInit[i][j] = Math.random();	
    		}
     
    		// On calcul les distances euclidiennes entre les points
    		for (int i = 0; i < n; i++)
    		{
    			for (int j = 0; j < i; j++)
    			{
    				distance[i][j] = dist(positionInit,i, j);
    				distance[j][i] = dist(positionInit,i, j);
    			}
    		}
     
    		// Le premier point a tout ces coordonnées nulles
    		// Le deuxième n'a qu'une seule coordonnée nulle
    		position[1][0] = distance[1][0];
     
    		/* On lance notre algorithme pour trouver les coordonnées des points 3 à n */
    		double zero=0;
    		for (int WichPoint = 2; WichPoint < n; WichPoint++)
    		{  
    			int i = WichPoint; // je met i juste pour simplifier le code, et Wichpoint pour comprendre de quoi je parle
    			// La norme du vecteur sera sa distance au point 1
    			double norme = SQR(distance[0][i]); 
     
    			// On calcul d'abord les n-2 premières coordonnées du point courant
    			for (int p = 0; p < i - 1; p++)
    			{
    				position[i][p] = norme - SQR(distance[p + 1][i])+ SQR(distance[p+1][0]);
     
    				double sumCoord = 0.0;
    				for (int j = 0; j <= p - 1; j++) 
    				{
    					sumCoord += position[i][j] * position[p + 1][j];
    				}
    				position[i][p] = position[i][p] - 2 * sumCoord;
    				position[i][p] = position[i][p] / (2 * position[p + 1][p]);
    			}
     
    			// On calcul enfin la dernière coord du point courant en utilisant les coord calculés à l'instant
    			double sumSQR=0.0;
    			for (int j = 0; j < i - 1; j++)
    			{
    				sumSQR += SQR(position[i][j]);
    			}
    			// Le dernier calcul devrait tjs etre vrai car norme > sumSQR (mathematiquement j'entend)
    			position[i][i - 1] = Math.sqrt(norme - sumSQR);
    			// Or y'a du NaN ???? donc norme < sumSQR et c pas normal !!!
     
    			// On test le dernier calcul voir quand apparait ce NaN
    			if(Double.isNaN(position[i][i - 1])==true && zero==0){
    				zero++;
    				System.out.println(" NaN at i=" + i );
    			}
    		}
     
    	}
     
    }

  2. #2
    Membre actif
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2007
    Messages
    241
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2007
    Messages : 241
    Points : 272
    Points
    272
    Par défaut
    Erreur NaN not a number, peut-etre essayes tu de faire un calcul avec une variable qui n'est pas un nombre ^o).

    Peux tu donner plus de préciser par exemple la fonction qui te lève cette erreur ou la ligne stp?

    A la ligne : sum = sum + SQR(..)
    j'aurai mis : sum += geotest.SQR(..); -> la fonction SQR étant static

    Regles en Java : le nom des classes commence par une majuscule, le nom d'une méthode commence par une minuscul, ce n'est pas obligatoire mais très fortement recommandé
    Linux because rebooting is just for adding medias

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    132
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mai 2007
    Messages : 132
    Points : 170
    Points
    170
    Par défaut
    Salut,

    le problème vient de la ligne.

    Dans ton code tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    position[i][p] = position[i][p] - 2 * sumCoord;
    Ici le code executé est
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    position[i][p] - (2 * sumCoord)
    et cette ligne peut retourner un nombre < 0

    en rajoutant le test
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (position[i][p] - 2 * sumCoord < 0){
                        System.out.println ("########test1");
                        System.out.println ("position[i][p]"+position[i][p]);
                        System.out.println ("sumCoord:"+2 * sumCoord);
                    }
    j'ai le resultat:
    ########test1
    position[38][32]12.291549694058448
    sumCoord:12.292289346651803

    Il y a peu-être un pb avec la précision ...

    Bon debuggage

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 15
    Points : 22
    Points
    22
    Par défaut
    Bonjour,

    Je pense que tu devrait utilisé des bigdecimal.

    La precision d'un double ne suffit pas pour ce genre de calcul avec des soustractions.

    par exemple

    double d1 = 1.000000000000001;
    double d2 = 1.000000000000002;
    System.out.print(d1 - d2);

    te renvoie : -8.881784197001252E-16


    en fait le probleme viens du fait que le nombre de chiffre signifficati est assez faible avec un double

    si on prend des bigdecimal :
    BigDecimal d1 = new BigDecimal("1.000000000000001");
    BigDecimal d2 = new BigDecimal("1.000000000000002");
    System.out.print(d1.subtract(d2));
    >-1E-15

    et même
    BigDecimal d1 = new BigDecimal("1.00000000000000000000000001");
    BigDecimal d2 = new BigDecimal("1.00000000000000000000000002");
    System.out.print(d1.subtract(d2));

    >-1E-26



    Donc bon courage pour passer tes element en bigdecimal !!!

  5. #5
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Au sujet de la précision, les doubles ne sont pas très "sûrs" au niveau des arrondis. Je crois qu'il vaut mieux travailler avec des BigDecimal.

    Par contre tu es obligé de passer par des méthodes vu que ce ne sont pas des types primitifs. Apres dans les librairies pour matheux il y a peut être des choses encore mieux ...
    "If email had been around before the telephone was invented, people would have said, 'Hey, forget email! With this new telephone invention I can actually talk to people!"

    Besoin d'une nouvelle méthode pour développer ? -> http://www.la-rache.com/

Discussions similaires

  1. Le futur site de l'UMP : Les créateurs de possible, pour 1,8 millions d'euros
    Par Pierre Louis Chevalier dans le forum Politique
    Réponses: 35
    Dernier message: 04/10/2009, 10h50
  2. Réponses: 7
    Dernier message: 29/07/2009, 15h40
  3. [Hadopi] Hadopi : Un cout de plus de 200 Millions d'Euros chez les F.A.I
    Par Pierre Louis Chevalier dans le forum Politique
    Réponses: 24
    Dernier message: 20/05/2009, 11h08
  4. Réponses: 1
    Dernier message: 28/06/2007, 18h05
  5. [erreur] Probleme Applet dans page HTML
    Par John Blobsmith dans le forum Eclipse Java
    Réponses: 4
    Dernier message: 10/07/2005, 14h49

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo