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