et ben vous chomez pas le weekend!
bonjour,
Ma matrice effectivement n'affiche pas de NaN, car en fait je me suis melangé, je vous en ai donné une qui donne du NaN si on calcul avec peu de precision. Oubliez cette matrice.
Concernant la dimension m = n-1 c'est bien ca qu'il faut avoir.
La matrice de position de depart peut avoir la dimension qu'on vut, t'en que y'a n lignes c'est bon. Il faut juste regler la boucle for dans le calcul de distance pour ne pas aller trop loin dans cette matrice position.
Ce qui ne changera jamais c'est que la matrice position finale est n*n-1, car c'est n points en dimension n-1.
concernant le code qu'on utilise, je me suis mis au dernier qui a été posté sur ce post, ca ne change rien de toute facon car il fait la même chose que le mien, mais est mieux ecrit.
Je l'ai juste modifié au niveau des affichages qu'il effectue.
En gros j'ai deux entier de choix : un pour selectionner si on veut donner la matrice ou si on la veut aleatoire
et l'autre pour dire quelles types d'informations on affiche.
Ah oui puis j'y ai rajouté un test de division par zero. Qui nous permet de verifier qu'on a du NaN sans avoir de division par zero. ( a verifier en tirant une matrice aleatoire)
voila ce que ca donne :
class Geotest {
final int NB_POINTS = 100;
// type Matrice de départ : 0 = c'est nous qui la créons ; 1 = aléatoire
final int typeMat = 1;
/* typeAffichage :
* 0 = on affiche toutes les étapes de calcul
* 1 = on affiche juste résultats
* 2 = on affiche juste quand y'a du NaN */
public int typeAffichage = 0;
// 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];;
// Matrice des positions reconstruites par l'algorithme
public double[][] coordonnees = new double[n][m];
// Matrice des distances
public double[][] distances = new double[n][n];
// vecteur pour controle de division par zero
// zeroPos[0]=position en i ; zeroPos[1]=position en j ; zeroPos[2] = valeur de coord
public double[] zeroPos = { -1,-1,-1};
// 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 creationMatrice(int type){
if(typeAffichage==0) System.out.println("Matrice Initiale");
switch(type) {
case 0 :
// ON cree nous même la matrice
double[][] temp =
{
{ 0.0, 0.0, 0.0 } ,
{ 2.0, 0.0, 0.0 },
{ 7.0, 0.0, 0.0 },
{ 0.0, 1.0, 2.0 }
};
for(int i=0;i<n;i++){
if(typeAffichage==0) System.out.print(i + "=> ");
for(int j=0;j<m;j++){
coordonneesInitiales[i][j]= temp[i][j];
if(typeAffichage==0) System.out.print(coordonneesInitiales[i][j] + " ");
}
if(typeAffichage==0) System.out.println();
}
break;
case 1 :
// On crée une matrice triangulaire aléatoire
for (int i = 0; i < n; i++) {
if(typeAffichage==0) System.out.print(i + "=> ");
for (int j = 0; j < i; j++) {
coordonneesInitiales[i][j] = (Math.random()*10);
if(typeAffichage==0) System.out.print(coordonneesInitiales[i][j] + " ");
}
if(typeAffichage==0) System.out.println();
}
break;
}
}
public void executeTest() {
creationMatrice(typeMat);
// On calcul les distances euclidiennes entre les points
if(typeAffichage==0) System.out.println("Matrice distance");
for (int i = 0; i < n; i++) {
//System.out.print(i + "=> ");
for (int j = 0; j < m; j++) {
distances[i][j] = dist(coordonneesInitiales, i, j);
distances[j][i] = dist(coordonneesInitiales, i, j);
if(typeAffichage==0) System.out.print(distances[i][j] + " ");
}
if(typeAffichage==0) System.out.println();
}
if(typeAffichage==0) System.out.println("Matrice Résultat (intermediaire)");
if(typeAffichage==0) System.out.print("1=> ");
// 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];
if(typeAffichage==0) System.out.println(coordonneesInitiales[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
if(typeAffichage==0) System.out.print(i + "=> ");
// La norme du vecteur sera sa distance au point 1
double norme = carre(distances[0][i]);
// 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]);
if(typeAffichage==0) System.out.print("p=" + p + " norme-d²=" + coordonnees[i][p]);
double sumCoord = 0;
for (int k = 0; k <= p - 1; k++) {
sumCoord += coordonnees[i][k] * coordonnees[p + 1][k];
}
if(typeAffichage==0) System.out.print(" sumCoord=" + sumCoord + " ");
coordonnees[i][p] = coordonnees[i][p] - 2 * sumCoord;
coordonnees[i][p] = coordonnees[i][p] / (2 * coordonnees[p + 1][p]);
if(typeAffichage==0) System.out.print(" x=" + coordonnees[i][p] + " ");
if(typeAffichage==0) System.out.println();
}
if(typeAffichage==0) System.out.println();
// 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)
coordonnees[i][i - 1] = (float)Math.sqrt(norme - sumSQR);
// on test si un des résultats s'approche de zero = controle division par zero
if(Math.abs(coordonnees[i][i-1])<0.0000001){
System.out.println(" petit resultat= " + coordonnees[i][i-1]);
zeroPos[0]=i;
zeroPos[1]=i-1;
zeroPos[2]=coordonnees[i][i-1];
}
// 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);
System.out.println(" Position du zero : i=" + zeroPos[0] + " j=" + zeroPos[1] + " coord="+ zeroPos[2]);
if(typeAffichage==0) typeAffichage=2; // on chg la valeur pour arreter l'affichage au NaN
}
}
if(typeAffichage==1) System.out.println("Matrice resultat");
for (int i = 0; i < n; i++) {
if(typeAffichage==1) System.out.print(i + "=> ");
for (int j = 0; j < i; j++) {
if(typeAffichage==1) System.out.print(coordonnees[i][j] + " ");
}
if(typeAffichage==1) System.out.println();
}
}
public static void main(String[] args) {
Geotest test = new Geotest();
test.executeTest();
}
}
et ben vous chomez pas le weekend!
bonjour,
Ma matrice effectivement n'affiche pas de NaN, car en fait je me suis melangé, je vous en ai donné une qui donne du NaN si on calcul avec peu de precision. Oubliez cette matrice.
Concernant la dimension m = n-1 c'est bien ca qu'il faut avoir.
La matrice de position de depart peut avoir la dimension qu'on vut, t'en que y'a n lignes c'est bon. Il faut juste regler la boucle for dans le calcul de distance pour ne pas aller trop loin dans cette matrice position.
Ce qui ne changera jamais c'est que la matrice position finale est n*n-1, car c'est n points en dimension n-1.
concernant le code qu'on utilise, je me suis mis au dernier qui a été posté sur ce post, ca ne change rien de toute facon car il fait la même chose que le mien, mais est mieux ecrit.
Je l'ai juste modifié au niveau des affichages qu'il effectue.
En gros j'ai deux entier de choix : un pour selectionner si on veut donner la matrice ou si on la veut aleatoire
et l'autre pour dire quelles types d'informations on affiche.
Ah oui puis j'y ai rajouté un test de division par zero. Qui nous permet de verifier qu'on a du NaN sans avoir de division par zero. ( a verifier en tirant une matrice aleatoire)
voila ce que ca donne :