Ajouter un commentaire

ltchris
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 ca fait partie 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 debute. 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 ..... :(

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 );
			}
		}
		
	}
	
}

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
  CCC  V     V  PPPP   TTTTTT  PPPP  
C V V P P TT P P
C V V PPPP TT PPPP
C V V P TT P
CCC V P TT P