Ajouter un commentaire

willbback
Je crois que je vais avoir le droit à la moitié du Million

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:

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 H  H  U   U  V     V   SSS    CCC 
H H U U V V S C
HHHH U U V V SSS C
H H U U V V S C
H H UUU V SSSS CCC