fredericmazue wrote:
double d = 1.0/0.0
ne la lève pas et affecte Infinity à d, alors que tu t'attendais peut être à une levée d'exception.
arf ce Java :twisted: Non j'exagère :) Beaucoup de langages font comme lui.
C'est déjà pas cool comme ça.
J'avais remarqué le risque de division par zéro, mais dans tous mes essais, je n'ai jamais vu "Infinity" dans les resultats affichés.
Je viens donc de refaire les essais avec ton code légèrement modifié.
class Geotest {
final int NB_POINTS = 40;
// n = nombre de points
// m = dimension de l'espace
private int n = NB_POINTS;
private int m = NB_POINTS - 1;
// Matrice des positions initiales
public double[][] coordonneesInitiales = new double[n][m];
// public double[][] coordonneesInitiales =
// {
// { 0.0, 0.0, 0.0 } ,
// { 7.0, 0.0, 0.0 },
// { 1.0, 0.0, 0.0 },
// { 7.0, 6.0, 5.0 }
// };
// Matrice des positions reconstruites par l'algorithme
public double[][] coordonnees = new double[n][m];
// Matrice des distances
public double[][] distances = new double[n][n];
// petite methode pour calculer un carre
double carre(double x) {
return x * x;
}
// Calcul de la distance euclidienne pour la matrice de position
double dist(double[][] coords, int a, int b) {
double sum = 0;
for (int i = 0; i < m; i++) {
sum = sum + carre(coords[a][i] - coords[b][i]);
}
return Math.sqrt(sum);
}
public void executeTest() {
// On crée une matrice triangulaire aléatoire
for (int i = 0; i < n; i++) {
for (int j = 0; j < i; j++) {
coordonneesInitiales[i][j] = Math.random();
if (coordonneesInitiales[i][j] == 0) {
System.out.println("******** coordonneesInitiales[i][j] ["
+ i + "][" + j + "] == 0 ********");
}
}
}
printMatrice("Matrice Initiale Complète", coordonneesInitiales);
// On calcul les distances euclidiennes entre les points
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
distances[i][j] = dist(coordonneesInitiales, i, j);
distances[j][i] = dist(coordonneesInitiales, i, j);
}
}
printMatrice("Matrice distance", distances);
// Le premier point a tout ces coordonnées nulles
// Le deuxième n'a qu'une seule coordonnée nulle
coordonnees[1][0] = distances[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 = carre(distances[0][i]);
if (norme == 0) {
System.out.println("******** norme [0][" + i + "] == 0 ********");
}
// On calcul d'abord les n-2 premières coordonnées du point courant
for (int p = 0; p < i - 1; p++) {
coordonnees[i][p] = norme - carre(distances[p + 1][i])
+ carre(distances[p + 1][0]);
double sumCoord = 0;
for (int k = 0; k <= p - 1; k++) {
sumCoord += coordonnees[i][k] * coordonnees[p + 1][k];
}
coordonnees[i][p] = coordonnees[i][p] - 2 * sumCoord;
if (coordonnees[p + 1][p] == 0) {
System.out.println("******** coordonnees[p + 1][p] ["
+ (p + 1) + "][" + p + "] == 0 ********");
}
coordonnees[i][p] = coordonnees[i][p]
/ (2 * coordonnees[p + 1][p]);
}
// On calcul enfin la dernière coord du point courant en utilisant
// les coord calculés à
// l'instant
double sumSQR = 0;
for (int j = 0; j < i - 1; j++) {
sumSQR += carre(coordonnees[i][j]);
}
// Le dernier calcul devrait tjs etre vrai car norme > sumSQR
// (mathematiquement j'entend)
if ((norme - sumSQR) <= 0) {
System.out.println("******** (norme - sumSQR) <= 0 "+ (norme - sumSQR) + "********");
}
coordonnees[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(coordonnees[i][i - 1]) == true && zero == 0) {
zero++;
System.out.println("NaN a " + i);
}
}
printMatrice("Matrice resultat", coordonnees);
System.out.println("Nombre NaN :" + zero);
}
private void printMatrice(String legende, double[][] matrice) {
System.out.println(legende);
for (int i = 0; i < n; i++) {
System.out.print(i + "| ");
for (int j = 0; j < m; j++) {
System.out.print(matrice[i][j] + " ");
}
System.out.println();
}
}
public static void main(String[] args) {
Geotest test = new Geotest();
test.executeTest();
}
}
J'ai eu un ensemble de valeurs à NaN sans pour autant avoir un Infinity. En français dans le texte, j'ai bien eu une valeur négative passée à la fonction racine carré (sqrt) sans pour autant avoir des valeurs à 0 dans les coordonnées.
Il existe donc 2 bugs :
_ Quand les coordonnées sont égales à 0
_ Quand les valeurs sont très petites, la somme "sumSQR" est supérieur à la "norme".
Lors d'un précédent post, j'ai évoqué le problème de la fonction "dist" qui accède à des valeurs dans la partie supérieur de la matrice triangulaire, donc des valeurs à 0.
Il est très probable que si les valeurs sont suffisament petites, le fait de "louper" une valeur dans le calcul de la distance fait que la "sumSQR".
Je continu donc à soutenir que la fonction "dist" a un problème d'indice.
Et pour fredericmazue, le meilleur langage qui existe est celui que chacun maîtrise le mieux (dicton de consultant) :lol:
C'est déjà pas cool comme ça.
J'avais remarqué le risque de division par zéro, mais dans tous mes essais, je n'ai jamais vu "Infinity" dans les resultats affichés.
Je viens donc de refaire les essais avec ton code légèrement modifié.
J'ai eu un ensemble de valeurs à NaN sans pour autant avoir un Infinity. En français dans le texte, j'ai bien eu une valeur négative passée à la fonction racine carré (sqrt) sans pour autant avoir des valeurs à 0 dans les coordonnées.
Il existe donc 2 bugs :
_ Quand les coordonnées sont égales à 0
_ Quand les valeurs sont très petites, la somme "sumSQR" est supérieur à la "norme".
Lors d'un précédent post, j'ai évoqué le problème de la fonction "dist" qui accède à des valeurs dans la partie supérieur de la matrice triangulaire, donc des valeurs à 0.
Il est très probable que si les valeurs sont suffisament petites, le fait de "louper" une valeur dans le calcul de la distance fait que la "sumSQR".
Je continu donc à soutenir que la fonction "dist" a un problème d'indice.
Et pour fredericmazue, le meilleur langage qui existe est celui que chacun maîtrise le mieux (dicton de consultant) :lol: