Ajouter un commentaire

ltchris

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

Filtered HTML

Plain text

CAPTCHA
Cette question permet de vérifier que vous n'êtes pas un robot spammeur :-)
 H  H   SSS   W     W  X   X  BBBB  
H H S W W X X B B
HHHH SSS W W W X BBBB
H H S W W W X X B B
H H SSSS W W X X BBBB