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 ); } } } }
Fallait pas...
Fallait pas non plus...
C'est que ci-dessous, ce n'est pas un algorithme qu'il y a, mais du code. Code qui, soit dit sans vouloir te peiner, est illisible. Il faudrait au moins respecter les conventions d'écriture. Geotest ou lieu de geotest. whichPoint au lieu de WhichPoint, carre au lieu de SQR (qui ressemble beaucoup trop à sqrt qui plus est), etc.
Ceci étant dit, après y avoir passé un bon moment car piqué par la curiosité, je dois dire que je ne suis pas parvenu à comprendre ce code.
Mais à priori, il n'y a pas "d'erreur de calcul typique de Java."
Je serais assez curieux de voir l'algorithme écrit ici, pour pouvoir voir s'il il a été traduit correctement en Java.
Parce que ce code, je le trouve très bizarre ainsi que ces commentaires. Exemple:
Comment ça une matrice triangulaire ? J'ignorais que l'on pouvait faire ça en Java. En Objective Caml oui, mais pas en Java ;)
arf ces informaticiens ... jamais content par le code qu'on leur donne :)
(moi je le trouve très lisible (après 1mois passé dedans forcement))
J'imagine bien que pris brut comme ça, ça doit pas le faire !
Bon j'ai un word avec l'algo qui est dispo, je vais virer les infos qui servent a rien, et je met ca sur le forum plus tard.
Merci en tout cas pour avoir passé un peu de tps sur mon probleme.
et hop, j'espere que ca t'aidera, ou au moins que ca t'embrouillera pas plus :
En entrer, j’ai une matrice de position positionInit[Nbpoints][Nbpoints-1] (triangulaire aleatoire, dans la pratique cette matrice sera donnée par les experiences) , grace à cette matrice je calcule les distances euclidiennes entre tout les points (methode dist) et donc j’obtiens une matrice de distance distance[Nbpoints][Nbpoints]
C’est sur cette dernière matrice que je vais lancer mon algorithme :
Il consiste à positionner les n points, dont j’ai les distances les uns par rapport aux autres, dans un espace à n-1 dimensions
- Pour le premier point, il faut initialiser ses coordonnées à 0. c’est l’origine de notre espace.
- Pour le deuxième on initialise sa première coordonnée grâce à la valeur de distance[0][1]
Ensuite nous allons lancer l’algorithme pour tout les points, du 3ème au nème. Donc on fera une première boucle for avec i le numéro du point, qui ira de 2 à n-1
Pour chaque point i, les i-2 premières coordonnées p sont calculées grâce à la formule mathématique suivante. Pour calculer ces coordonnées on aura donc une deuxième boucle for avec p allant de 0 à i-2 :
Une fois les n points calculés, on arrête l’algorithme, et on a donc n points avec n-1 dimensions.[img]http://www.edp6.jussieu.fr/etudiants/becavin/equ1cercle.bmp[/img]
Dans cette formule l’élèment x^i_p = position[i-1][p-1] (variable position[][] de mon code)
Et l’élèment d_i_p = distance [i-1][p-1] (variable distance[][] de mon code)
Une fois la boucle for sur le p terminée, il reste la dernière coordonnée à calculer, en utilisant l’équation suivante :
[img]http://www.edp6.jussieu.fr/etudiants/becavin/equ2cercle.bmp[/img]
edit : merde les images s'affichent pas ?? pas le tps de m'en occuper je dois partir, je met un lien html vers les equations
En effet :)
Quoiqu'on pourrait argumenter qu'une heure devrait suffire .... :twisted:
Ben...
D'ailleurs.. je ne voudrais pas trop remuer le couteau dans la plaie...mais ça ne le fait pas pour toi non plus :)
Je dois être particulièrement obtu ce soir, mais je n'arrive pas à voir en quoi cette matrice rectangulaire est triangulaire :twisted:
Déjà ça je comprends mal. Je veux dire que si tu fais ça, (et tu le fais au tout début du code) c'est comme si il y avait une origine à ton espace Donc je vois pas pourquoi tu (re)définis l'origine de cette espace après
Ca c'est le but à atteindre, ce n'est pas un algorithme
Bon ok, quoi que l'intérêt reste pour moi à éclaircir.
Et la deuxième coordonnée ? Serait elle nulle ? Ca voudrait dire que tu orientes alors ton repère.
Y a pas à dire c'est le changement d'origine le plus tordu que j'ai jamais vu (à moins que je ne comprenne rien, ce qui est à envisager très sérieusement semble-t-il).
Pourquoi ne pas (simplement) retrancher à tous les points les coordonnées du point définissant la nouvelle origine. ?
Et puis il y a ça aussi que je ne comprends pas:
Dans un espace à n-1 dimensions, les points devraient avoir n-1 coordonnées non ?
:?:
je devrais sans doute retourner un peu sur les bancs d'école moi.
ou alors il faut lire "n points avec n-1 distances entre eux" :?:
J'ai tracé l'éxécution de ton programme, surtout après avoir enlever toutes les variables et fonctions statics.
Il n'y a pas de dépacement de capacité ou d'autre effet de bord sur les calculs. Les traces de l'éxécution montrent bien que la différence est négative :
Le problème est bien dans le calcul.
C'est pas du luxe... ;)
C'est ce que j'avais constaté aussi. Dis je ne voudrais pas mourir idiot... Tu as compris toi ce qu'il veut faire ? Et pourquoi il fait un changement de repère de la façon dont il le fait ? Je n'arrive pas à saisir...
sorry de répondre aussi tard (c'était pour laisser un suspens ... que vous trouviez pkoi je voulais faire ce programme).
alors en fait, ce que je vous ai montré est la version de test la plus simple que je puisse donner, donc c'est impossible de comprendre ce que je veux faire avec ce programme en ayant juste cette version.
Je vais donc vous dire ce que je veux faire comme vous êtes curieux.
C'est un sujet de doctorat que je viens de débuter. Il s'agit de prendre les données tirées d'experience de puce à ADN (chercher sur wikipedia pour info). De ces expériences, je tire un tableau de données de n*34000
n représente les différentes types de cellules observées (qu'on appelle condition biologique), et 34000 le nombre de niveau d'expression de gènes qu'on observe.
De cette très grande matrice, on extrait une matrice de n*n comprenant les distances entre les diffèrentes conditions biologiques.
Utilisant cette matrice je veux alors représenter mes n points dans un espace euclidien. Cet espace aura n-1 dimensions pour ne perdre aucune information.
donc dans mon programme finale ce qu'il y aura en entrée sera la matrice de distance. Mon programme de test genère lui meme cette matrice distance en creant aléatoirement une matrice de position (triangulaire car y'a des zero partout sauf sur le triangle inferieur). Mais dans la suite la valeur de cette matrice position n'a aucun interet. il ne faut donc pas comparer les matrices position de depart avec celle de fin, elles n'ont aucun lien. Et dans la pratique finale, elle n'auront meme pas la meme dimension.
Le but est vraiment : representer n points dont j'ai les distances les uns par rapport aux autres dans un espace euclidien.
Pour reparler du bug, j'avais deja vu ouais que norm devenait plus petit que sumCoord vers la fin, mais je n'en ai pas trouvé la raison.
sur d'autres forum on me parle de la precision, et d'utiliser BigDecimal . Je vais tester ca j'ai rien a perdre...
C'est ce que j'avais constaté aussi. Dis je ne voudrais pas mourir idiot... Tu as compris toi ce qu'il veut faire ? Et pourquoi il fait un changement de repère de la façon dont il le fait ? Je n'arrive pas à saisir...
Moi, je ne suis qu'un bête développeur, je code que ce qui est dans les spécifications. :shock:
Concernant la précision, je veux bien croire qu'il ya un problème de précision, mais reste quand même beaucoup de problème d'algorithmie dans ce "bout de code".
Je suis loin d'être une super tronche en math, donc loin de moi l'idée de critiqué les formules mathématiques. Mais là, l'écart entre les 2 nombres produisants la valeure négative est tout de même proche de 2, ce qui fait beaucoup pour une imprécision de calcul sur un nombre si petit.
De plus, l'ordre de grandeur de chaque nombre devient très vite significatif, j'ai fait des éxecutions en faisant varier le nombre de points. Le problème ne se produit pas toujours au même endroit, et la fréquence est relativement rare en dessous de n=47.
Je pencherais plus sur un problème de donnée.
A au fait, voici le code un peu nettoyé
Sauf que c'est une matrice rectangulaire. (arf ces programmeurs... oui je sais ... ;) )
Faut pas écouter ce qu'on dit sur les autres forum ;)
wilbback a tout à fait raison à mon humble avis. J'ai moi même hier regardé brièvement sous deboggueur et j'ai vu des valeurs négatives de 0.2 ce qui est de même beaucoup pour une imprécision. Et même beaucoup trop vu le peu de calculs effectués sur les nombres. Le problème de précision ne me parait pas vraisemblable.
En tous cas mon ampéropifomètre à ondultions synthétiques vibro-quantiques me suggère que les calculs pourraient bien être faux.
Du moins mon expérience d'informaticien (arf) me fait penser que c'est plus probable qu'un erreur de précision.
Cool, un joli code tout propre d'informaticien :)
Malheureusement vous confirmez, ce que je pensais depuis le debut. Avec des resultats avec aussi peu de chiffre avant la virgule (1 , 2 max) il me parait bizarre que des erreurs de precision apparaissent.
Et les calculs je l'es ai verifié 20 fois ... (d'ou les presque 1mois de recherche de bug=verif calcul + verif divergence quelconque + c quoi ce bordel putain)
Je sens que je vais essayer de faire totalement différement mon truc, car ca fait chié !
Merci bcp en tout cas pour l'aide, si vous voyez quelque chose d'autre prevenez moi ...
Décidément, mon patron va finir par me virer à force de jouer avec ce merveilleux algorithme.
Voici le code que j'ai mis en place
J'ai fait plusieurs éxécutions avec n=10 pour ne pas faire trop apparaître de résultat.
J'ai transformé l'affectation aléatoire pour donner un nombre entier compris entre 0 et 9 afin de limiter l'influence d'une imprécision de calcul.
J'ai fait également afficher les différentes matrices produites (avec un joli effet de mise en page pour bien tout voir :lol: )
Voici le résultat :
La lecture de se résultat montre que :
le test du NaN ne reporte pas toutes les erreurs
le NaN se trouve gentiellement réparti après le 2ème colonne de la matrice
Je pense qu'il est peut-être nécessaire de revérifier l'algorithme d'implémentation. Un petit problème de déplacement dans la Matrice peut-être ?
Juste pour info, Math.sqrt fonctionne qu'avec des doubles, donc la précision restera égale à l'imprécision des doubles, quoi que tu fasses
On voit aussi (matrice intermédiaire et résultat) des valeurs proches de 0 ou 1 systématiquement ce que ne me parait pas normal.
L'algorithme semble donc bien faux. A l'expérience je voterais pour une subtile confusion d'indice entre indices des formules mathématiques et indices d'accès aux valeurs des matrices.
Le challenge est intéressant. Dès que j'ai un moment j'essaie d'y voir clair, maintenant que j'ai enfin saisi le problème à résoudre (ca a été dur...)
ben le probleme d'indice ca été ce que j'ai essayé de résoudre en premier. Et si il y en avait tjs un, ne pensiez vous pas que ca donnerai un resultat faux des le debut ?
si le challenge vous interesse, peut etre pouvez vous essayer de reprendre depuis le debut, il suffit de vous posez la question :
comment, si j'ai des distances entre des points, representer ces points dans un espace à n-1 dimensions, un espace euclidien ou en calculant la distance entre ces points j'aurai exactement la matrice de distance de depart ?
Je me doute bien que vous y avez pensé.
A propos de résultat faux, la première chose que je vais faire est d'essayer votre code sur 4 points (constants plutôt qu'aléatoires pour commencer), donc (si je comprends bien) dans un espace à trois dimensions que je peux me représenter dans ma petite tête obtue. Je ferai d'abord les calculs à la main et vérifierai dans un premier temps que le code donne le même résultat.
Vous l'avez fait ce test ?
yep!
avec qu'il y est le NaN je verifie que le calcul est exact à 10^-17 pres , soit la precisiondu double. Je vois mal comment pourrai y avoir un probleme d'indice.
Je vois mal le rapport, Si Nan il y a, problème quelque part il y a.
Faut dire ausis que j'ai du mal à comprendre votre phrase. "Nan il y a" et "calcul exact" Comment ça ?
De toutes façons ça sera soit ça soit que les formules mathématiques sont fausses. Bon bien sûr elles sont peut être mal transcrites, mais après un mois de vérif ça semble peu probable.
Arf ces scientifiques, tous pareils :twisted:
Désolé je n'ai pas pu me retenir :oops:
Etant super nul en math, je n'oserais pas faire de remarque sur les formules. Concernant le parcours de tableaux à l'aide d'indice, ça je connais (débordement de pile, etc...).
J'ai pris votre algorithme, j'ai remplacé les types primitifs double des tableau en objet Double. Et là, petite surprise, ça ne marche plus du tout car j'ai un superbe et tant redouté "java.lang.NullPointerException".
Ce qui signifie tout simplement l'accès a une valeur non initialisée dans le tableau (ce phénomène ne se produit pas avec les types primitifs car la valeur par défaut est 0 en java).
Effectivement, vos indices de parcours ne dépassent pas la limite de votre tableau, ça c'est géré, en revanche, la matrice étant triangulaire inférieure, le calcul de distance (puisque c'est de là qu'intervient l'erreur java) accède à la partie supérieure de la matrice (celle remplit de 0).
J'espère que ce point va vous aider. Si vous avez besoin de plus de détail "java" pour reproduire l'erreur, je vous soumettrais mon code transformé, mais il n'est pas un exemple à suivre pour les développements, c'est juste pour la validation des indices dans votre cas.
Bon courage
Bon, j'ai regardé un peu et je pense pouvoir aider.
J'ai repris le code de willbback (merci à lui :) )
Je me suis permis de renommer quelques variables pour la clarté. renommer aussi un j en k pour que ça colle mieux à la formule mathématique donnée dans le lien, etc.
Mais c'est du détail. Voici le code toutefois:
J'ai encore limité les essais à N = 4, ce qui est largement suffisant pour y voir clair.
Voir un premier résultat
Ici tout marche bien, ou du moins tout semble.
Voici un second résultat:
Là c'est beaucoup plus amusant .... et instructif. :twisted:
Il y a du Nan d'accord, mais surtout de l'Infinity. Et on comprends tout de suite.
Quand on a des coordonnées (autres que la première) nulles, cela provoque une division par zéro ici
coordonnees[i][p] = coordonnees[i][p] / (2 * coordonnees[p + 1][p]);
Quand coordonnées [p+1][p] vaut zéro :twisted:
Le Nan n'est qu'un corollaire de ça
Voci un code tout cuit avec cet exemple pour le vérifier
Division par zéro....
arf ces scientifiques :twisted:
Désolé je n'ai pas pu me retenir. :oops:
Mais au delà de la taquinerie, j'espère très sincèrement que ça t'aidera :)
Au fait pour le million d'Euro, où dois je facturer ? :D
Un petit complément:
Finalement il y a bien un facétie de Java à laquelle tu ne t'attendais peut être pas. En effet
int i = 1/0
lève une exception DivisionByZeroException
tandis que
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é.
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:
J'ai pas lu ton code. (pas beaucoup le temps ce matin.) Mais je garantis que le mien a bien des Infinity et qu'il y a bien division par zéro.
C'est aussi mon avis.
Je pense que ça devrait pouvoir se régler en testant ces conditions. Si on tombe dessus, alors on suspend le calcul, on translate d'un vecteur bien senti tous les points déjà calculés, et on reprend le calcul.
C'est possible. Je n'ai pas appronfondi la question. Si j'ai le temps j'essaierai de voir ce soir.
Je n'ai pas regardé non plus hier, car nous avons posté quasiment en même temps hier et je n'avais pas encore lu ton post en postant le mien.
Le meilleur langage est celui qui convient le mieux au travail à faire. Dicton de non consultant :lol:
Et dans la grande majorité des cas (sauf applet bien sûr :twisted:) ça n'est pas Java ;) :lol:
Ca parait quand même incroyable que tu n'ais pas Infinity. Comme j'étais fatigué l'autre soir, j'ai vérifié ce matin ce que j'ai dit plus haut et ca fait bien comme j'ai dit.
J'ai aussi essayé ce matin
qui donne
Sur JVM 1.6.0_02-b06
Quelle JVM tu as ?
Non non on se marre pas, les JVM sont pleines de surprises...
Je parlais de mes essais à moi (avec le Math.random). Avec ton code, j'ai bien "infinity", peut importe la JVM (1.4 et 1.5 avec des brouettes derrière).
C'est pour celà que j'ai réécrit le code en gardant le Math.random. J'ai ajouté un contrôle sur l'affectation d'une valeur à 0 par le Math.random et un test s'il y a une division par 0. Or mon joli message pleins de "****" ne s'affiche pas et pourtant j'ai des NaN en sortie.
Donc, la division par 0 n'est pas la seule explication.
Le phénomène du NaN ne semble pas apparaître si on multiplie par 10 le Math.random, ce qui faisait soupçonner l'imprésion de calcul. Mais lors que l'on fait affiché la différence entre "norme" et "sumSQR", il y a plus de 1 et nom pas un chiffre type -0,0000000001 par exemple. Il y a donc un réel écart entre les 2 nombres.
On peut me répondre par " c'est normal, celà correspond à la somme des incertitudes cumulées dans sumSQR". C'est effectivement une possibilité, mais la variable norme suit le même principe. Et pourquoi, lorsque que l'on affecte la matrice par des valeurs croissantes, nous n'avons plus le même problème avec par exemple (Math.sqrt(i*j+1))/100.
Et il y a le phénomène de lecture de la partie supérieure de la matrice, remplit de 0. Dans le cas d'un très petit nombre, le fait de manquer d'une valeur peut entraîner suffisament d'écart pour que sumSQR soit supérieur à norme.
Je pense que je vais arrêter là, car nous n'avons plus vu notre ami à la matrice :cry: donc, je ne sais pas si les recherches servent à quelques choses, ou nous sommes en train de nous livrer une bataille d'algorithme juste pour le plaisir, et je ne voudrais pas lancer de Troll sur la qualité des langages et encore moins Java, car je suis payé suffisament cher pour défendre ce langage auprès de mes clients par ma société (Ah! le vil prestataire que voilà) 8) .
Si j'ai encore le courrage, je tenterais bien une double exécution du programme avec les mêmes valeurs, la première fois affectée directement, la seconde fois trié par ordre croissant et voir éventuellement avec un ordre décroissant, juste pour voir si la croissance des coordonnées a une influence sur le problème de calcul. Il est aussi possible de remplir la matrice avec la plus petite valeur double possible afin de voir comment le phénomène se produit. Bref un peu d'expérimentation. Mais comme notre ami ne semble plus s'intéresser au problème, je vais retourner à mon laborieu travail ..... en Java
votre ami à la matrice est toujours la :) et lis vos post avec interet.
De mon cote j'ai trouvé d'autres comportements bizarre, qui me laisse soupconner que effectivement y'aurai un probleme du cote du calcul de distance (qui pourtant est le calcul le plus simple que le calcul scientifique puisse admettre).
J'ai fait d'autres trucs ces deux derniers jours, mais la je m'y remet, et ce soir j'aurai trouvé !!! (a moi mon million d'euros :D )
Il y a aussi le problème de la division par 0, bien réel, et vu plusieurs fois par mes petits yeux porcins.
ouaip aussi. De manière generale c'est la partie division qui peut foutre la merde apparement!
Putain mais c ca !!!!
J'ai relu les messages que vous avez posté. l'histoire du zero au depart je prenais ca comme quelque chose qui arrive parfois si on prend une matrice particulière.Mais en fait y'a bien un gros probleme mathematique derriere!
J'ai considérais quand j'ai fait mon algo que j'aurai jamais de position nulle, sur la diagonale de ma matrice, or je peux en avoir. Je suis entrain de voir pkoi ca fait ca au niveau des math !
On arrête pas de te le dire :lol:
Lol :lol:
Arf.... si tu vois ce que je veux dire ;)
Bon tu dois être content que le problème se débloque.
Bon, je répète ma question: pour le million d'Euro, où dois je facturer ? ;)
sauf que la question ne se debloque pas totalement !
effectivement qd y'a des zeros ca peut pas marcher. Et Mathématiquement ca ne remet pas en cause mes calculs, ca correspond au cas ou mon systeme linéaire n'est pas solvable (car en fait c un systeme linéaire qu'on resous depuis le debut) car le determinant de la matrice positionfinale est nulle. Cas que j'avais mis de cote, avec toute mon arrogance de jeune loup !
Mais le lien entre "y'a des zeros", et "y'a du NaN" et pas encore acquis, car y'a du NaN sans que j'ai des zeros.
Donc le probleme reste, mais on avance .... Merci à vous ...
Je regarde encore un peu le truc jusqu'a 19h, et pour le reste on verra Lundi !
bon weekend à tous
L'homme à la matrice
Je veux donc mon million d'Euro.
Arf... ;)
Je dirais, toujours avec l'aide de mon ampéro-pifomètre, que le problème est le même.
N'y aurait-il pas du NaN quand il y a du "presque zéro", des valeurs très petites quoi. D'ailleurs willbback te l'a suggéré dans un de ses posts je crois.
et bien non le probleme est pas résolu donc pas de million d'euros :o (comment se sortir de cette situation ? ... changer le nom du post ? non ca va se voir ! .... je suis dans la merde :cry: )
Alors : oui ! mais non !
Car j'ai des matrices ou on divise par des nombres pas du tout petit, et on a du nan quand meme !
par exemple cette matrice :
ou y'a du NaN à 3.
On ne fait jamais de division par un nombre petit mais on a du NaN !
Bon weekend, faut vraiment que je parte!
Merci encore pour toute vos contribution !!!
et Bonne année ...
Pour qu'on parle bien tous de la même chose, peut tu poster, fut il horrible ;) le code avec lequel tu travailles maintenant, si tu as fait des changement par rapport au tout premier code que tu as posté.
Parce que là je viens d'essayer ta matrice avec ton premier code et elle fait pas de Nan sauf erreur de ma part.... :shock:
Effectivement, avec le dernier code posté (le mien en l'occurence) la matrice ne présente pas de NaN. Nous avons donc un écart de code avec toi.
La seul remarque que je peux faire, c'est que cette matrice est carrée et non plus n*m comme indiqué par
La définition de m n'est peut-être pas bonne dans ton algorithme.
Résultat avec m=NB_POINTS - 1
Résultat avec m=NB_POINTS
Le parcours dans le 2ème cas est complet pour la matrice, ce qui n'est pas le cas dans m=n-1
Qu'est-ce que tu racontes ?
d'un côté (code d'origine)
et mon code
C'est bien la même chose non ? :lol:
C'est juste que mon code est plus lisible à mon goût.
Entre outre mon code marche très bien parce qu'avec "une matrice qui va bien" il restitue convenablement les coordonnées des points comme je l'ai dit dans un post précédent
Par contre quand j'ai dit dans mon post précédent ne pas obtenir de NaN avec la dernière matrice de Itchris, ce n'était pas avec mon code, mais avec le sien, celui qu'il a posté en tout début. :twisted:
Et je maintiens qu'il n'est pas exclu que ces différences viennent de JVM différentes sous des OS différents. Là je suis sous Windows. Peut être Itchris est sous Linux. Les différences de calculs entre JVM avec des (très) petits nombres ça c'est déjà vu. Pourquoi est-ce que je parle de petits nombres ? Parce que si on a vu le problème de la division par zéro. En informatique, il faut se préoccuper de la division par "presque zéro". Tu as contasté qu'avec des "grand nombres" dans la matrice ça allait mieux, et je l'ai constaté aussi. Avec des grands nombres sans coordonnés nulles le code de Itchris (ou le mien puisque c'est le même ré-écrit) fonctionne très bien. Par exemple pour cette matrice
Par contre avec de très petits nombres, donc des divisions par presque zéro, rien n'est garanti. d'ailleurs quand j'aurais une minute, je vais essayer exactement les mêmes calculs que ceux faits jusque là avec une autre version de JVM et sous Linux, juste pour voir :)
Je viens de faire un essai avec la même version de JVM sous Linux et sous exactement la même architecture matérielle et je n'ai pas vu de différence dans les résultats. MAIS le code de Itchris avec sa dernière matrice ne me donne pas non plus de NaN....
C'est par rapport au code de ltchris. La matrice qu'il présente dans ses résultats est carré et non plus n*m. Je pense donc que nous (toi et moi) n'avons plus la dernière version du code sur lequel il travail . C'est juste une constatation tirée de son dernier poste.
Et effectivement avec les valeurs postées par ltchris, je n'ai pas de NaN non plus. Je suis donc en parfait accord avec tes dires :wink:
J'essaye de reprendre les formules qu'il a posté précédement mais j'ai quelques problèmes d'interprétation. Le calcul de la distance est fait en colonne dans la matrice, les calculs suivants sont fait en ligne. Je suis donc un peut surpris de la progession "cahotique" des indices. Mais ce n'est qu'une intuition mal placée de développeur.
Par exemple la norme est calculée par norme= carre(distances[0][i]), ce qui indique une variation de colonne dans la matrice, les coordonnées sont calculés par coordonnees[i][p] = norme - carre(distances[p + 1][i]) carre(distances[p + 1][0]), qui effectue une variation mélangée colonne et ligne. Mon instinct me dicte plutôt une ligne du type
coordonnees[p][i] = norme - carre(distances[p + 1][i]) + carre(distances[p + 1][0]). Avec un inquiétude sur p + 1. Lors d'une boucle sur p, il est rare d'essayé d'aller voir l'item suivant. Bref, je me pose bien des questions.....
Ou alors, il essaye d'inversé la matrice, et là le parcours n'est pas bon non plus. Mais vu que je ne comprends toujours pas la finalité du "bidule", j'ai du mal.
Il serait peut-être temps de poser le problème en terme plus simple, sans grande théorie mathématique, du genre : je calcul la distante entre le début de la colonne de la matrice initiale jusqu'à un point donné avec la formule ...
Ah ok, je ne t'avais pas bien lu :oops:
Alors pour cette histoire de NaN ici et pas là et aussi ce que je dis à propos des JVM: Je sais bien que j'ai comme une petite tendance à troller sur Java, une sorte de réflexe quoi, et certains peuvent penser que du coup je délire un peu.
J'invite ceux qui penseraient ça à lire l'article "How Java’s Floating-Point Hurts Everyone Everywhere" que l'on peut trouver à http://www.cs.berkeley.edu/~wkahan/JAVAhurt.pdf
Et l'article n'a pas été écrit pas des truffes :)
Arf... Java :lol:
Je viens de passer le code de double vers BigDecimal et................. Nous avons toujours des problèmes de NaN. Bref, quand les nombres sont trop petits y a un gros problème....
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 :
Et par presque zéro ?
Math.abs(coordonnees[i][p])<0.0000001
c'est le test que j'effectue
donc presque zero est parfaitement englobé dans ce test
oups !
mon test etait mal placé, il faut tester le calcul de la dernière coordonnée. J'edit mon code posté juste avant!
edit : hop c fait!
toujours pas de "presque zero"
Hum... On a pas la même notion du presque. .0000001 c'est gros ça ;)
Et puis moi surtout j'aurais testé coordonnees[p + 1][p] et juste avant de faire la division
Laissons tomber les "petits"
Je viens de faire quelues essais aves des matrices contenant des nombres microscopiques et je n'ai pas vu de problème.
Je dirais même plus, avec des matrices sans zéros mal placés, je n'arrive pas à avoir de Nan.
Ben justement 0.000001 c'est gros, et meme avec ca, je rentre jamais dans le if. donc on est vraiment loin du "presque zero" a chaque fois.
en fait je me suis trompé au debut d'ecrire le code, le vrai test c'est (j'ai édité le gros code depuis):
if(Math.abs(coordonnees[i-1])<0.0000001){
Car les divisions se font tjs avec ces élèments. Ca ne sert a rien de tester autre chose.
Pour resumer notre probleme :
- on a parfois des nombres petites, donc il faut faire un test de "nombre petit" : j'en fait mon affaire
- on a du naN meme quand y'a pas de division petite.
statistiquement sur des matrices aleatoires le NaN est plus proche quand on passe de double à float (testé), et si on prend des nombres plus grand dans la matrice aléatoire (testé).
y'a donc bien une idée de precision et de divergence, mais ce n'est pas du à de la division par zero dans la majorité des cas !
Le million d'euros[i]congratulations est toujours en jeu ...
Ca j'avais remaqué, mais la question est :
n'as-t'on pas du tout de NaN ? ou alors se produit'il trop loin pour qu'on l'observe ?
Ok
Qu'est-ce que quoi comment ?? :shock:
Tu veux dire que quand par exemple tu as des nombre qui se balladent de E-37 à E-38 (passage de float à double si ma mémoire est bonne) tu as du NaN ?
Bon je n'ai peut être pas compris ce que tu veux dire, mais ça ne semble pas faire de sens ce que tu dis, parce que les nombres sont tous doubles dans ton code et normalement la JVM va les coder sur 8 octets tout le temps. Et non pas une fois 4 une fois 8. C'est du Java, mais quand même ;)
Tu aurais une matrice toute prête qu'il n'y aurait qu'à copier-coller dans le code ? Je voudrais bien voir ça de mes petits yeux porcins je dois dire.
Pages