Problème avec une simulation informatique
Bonsoir, je ne sais pas si je dois poster dans Probas ou dans Informatique, je tente dans Probas.
J'ai un couple de variables aléatoires compliqué $(X,Y)$ (pas indépendantes) à valeurs dans $]-\pi;\pi]^2$, que je sais simuler informatiquement (j'ai ma fonction $\texttt{SimulXY()}$ en Python qui a l'air de marcher). Je m'intéresse à l'espérance (conditionnelle) de $\cos(X)+\cos(Y)+\cos(X+Y)$ sachant $\sin(X)+\sin(Y)=\sin(X+Y)$.
Pour ça, j'ai fait le programme suivant :
T0=[] n=0 while n<1000: (x,y)=SimulXY() if np.sin(x)+np.sin(y)==np.sin(x+y): n+=1 T0.append(np.cos(x)+np.cos(y)+np.cos(x+y)) print(sum(T0)/1000)
Ensuite, je réfléchis, et je me dis que $\sin(X)+\sin(Y)=\sin(X+Y)$ équivaut à $X=0$ ou $Y=0$ ou $Y=-X$. De plus, étant donné la tête de mes variables aléatoires, ces 3 cas sont incompatibles, donc je me dis que je vais regarder ce qu'il se passe dans chacun de ces 3 sous-cas :
T1=[] T2=[] T3=[] n=0 while n<1000: (x,y)=SimulXY() if np.sin(x)+np.sin(y)==np.sin(x+y): n+=1 u=np.cos(x)+np.cos(y)+np.cos(x+y) if x==0: T1.append(u) if y==0: T2.append(u) if (x+y)==0: T3.append(u)
Un peu plus tard, je ne retrouve plus mon fichier avec mes programmes. Je décide de re-simuler le cas $X=0$. Étant donné que $X=0$ implique $\sin(X)+\sin(Y)=\sin(X+Y)$, je n'ai pas besoin de mettre le $\texttt{if np.sin(x)+np.sin(y)==np.sin(x+y)}$. Je fais directement :
T4=[] n=0 while n<1000: (x,y)=SimulXY() if x==0: n+=1 T4.append(np.cos(x)+np.cos(y)+np.cos(x+y)) print(sum(T4)/1000)
Je ne comprends vraiment pas pourquoi et ça me rend fou. Est-ce que quelqu'un aurait une explication ?
Réponses
-
Je n'arrive pas non plus à voir le problème en survolant les codes.Pour comprendre ce qu'il se passe, je serai tenté de fabriquer toutes les listes dans une seule boucle while (et donc avec les mêmes simulations) pour les comparer à la fin.Édit : Dans une première réponse, j'avais mentionné la possibilité que l'erreur puisse venir de la présence de tests d'égalité avec des nombres flottants dont je ne suis pas sûr du comportement en Python.
T0 = [] T1 = [] T2 = [] T3 = [] T4 = [] n=0 while n<1000: (x,y)=SimulXY() if np.sin(x)+np.sin(y)==np.sin(x+y): n+=1 u=np.cos(x)+np.cos(y)+np.cos(x+y) T0.append(u) if x==0: T1.append(u) if y==0: T2.append(u) if (x+y)==0: T3.append(u) if x==0: T4.append(np.cos(x)+np.cos(y)+np.cos(x+y))
-
Sans parler du problème de l'égalité de nombres flottants soulevée par MrJ, le tout premier code me surprend. Sauf cas très particuliers (et dépendance vraiment très forte) sur la loi (X,Y), il est tout à fait improbable d'obtenir une égalité parfaite np.sin(x)+np.sin(y)==np.sin(x+y) même sur des millions d'itérations (d'autant plus que de manière standard le flottant Python est sur 64 bits).
Ce serait à mon avis utile d'en savoir plus sur (X,Y). Es-tu sûr que les 3 cas évoqués sont incompatibles ? As-tu essayé avec des else if et pas juste des if dans ton deuxième code pour voir la différence ?
-
MrJ a dit :J'avais mentionné la possibilité que l'erreur puisse venir de la présence de tests d'égalité avec des nombres flottants dont je ne suis pas sûr du comportement en Python.
Je pense que c'est ça le problème. Les programmes que j'ai postés sont des simplifications. En réalité, je ne teste pas vraiment une égalité, mais je teste en mettant "si la valeur absolue de la différence est plus petite qu'un epsilon". Je ne l'ai pas signalé parce que j'ai testé avec plusieurs valeurs de epsilon (voire différentes valeurs à différents endroits du programme) et que ça ne changeait rien, mais ça vient peut-être quand même de là.
-
Version légèrement modifiée du programme de MrJ + Vérification qu'on n'a pas de recoupement entre les 3 cas :
T0 = [] T1 = [] T2 = [] T3 = [] T4 = [] n=0 while n<10000: (x,y)=SimulXY() if abs(np.sin(x)+np.sin(y)-np.sin(x+y))<0.001: n+=1 u=np.cos(x)+np.cos(y)+np.cos(x+y) T0.append(u) v=min([abs(x),abs(y),abs(x+y)]) c=0 if abs(x)==v: T1.append(u) c+=1 if abs(y)==v: T2.append(u) c+=2 if abs(x+y)==v: T3.append(u) c+=4 if c not in [1,2,4]: print("Avertissement") print([c,(x,y,x+y,np.sin(x)+np.sin(y)-np.sin(x+y))]) if abs(x)<0.001: T4.append(np.cos(x)+np.cos(y)+np.cos(x+y))
Résultat : aucun avertissement. Résultats numériques :>>> print(np.mean(T0)) 0.48943685220073985 >>> print(np.mean(T1)) 0.497922408071928 >>> print(np.mean(T2)) 0.4924253674913608 >>> print(np.mean(T3)) 0.47794841317695635 >>> print(np.mean(T4)) 0.18962312055618538
-
Dans le dernier code que tu postes, tu testes : if abs(np.sin(x)+np.sin(y)-np.sin(x+y))<0.001
ok.
Et ensuite, tu splittes en différents cas, mais tu testes avec x , y et x+y, au lieu de sin(x), sin(y) et sin(x+y) ; si $x$ est proche de $\pi$, tu ne récupères pas x, mais y avec l'instruction v = min ( abs(x), abs(y), abs(x+y) ) .
Je pense que quand tu affiches tes print(np.mean(T0)), etc, tu devrais aussi afficher le nombre d'éléments de T0 ; tu y gagnerais en visibilité.Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
Le problème ne viendrait-il pas du fait que $X$ et $Y$ peuvent être proches de $\pm \pi$ simultanément ? Cela rendrait l'égalité $\sin(X)+\sin(Y) = \sin(X+Y)$ "presque" vraie.
-
Bonjour,
Est-ce que (X,Y) est une va continue ou discrète ? Et si tu peux donner SimulXY, ça pourrait nous permettre de faire des petits tests. -
@Calli : C'est une v.a continue. Code de SimulXY, si vous voulez tester (en tout cas, merci de vous intéresser à mon problème)
import numpy as np rng=np.random.default_rng() def SimulXY(): (X,Y,Z)=(0,0,1) constante=1/(24*(np.pi**2)) while Z>constante*(6 - 4*np.cos(X - Y) - 4*np.cos(X + 2*Y) - 4*np.cos(2*X + Y) + 4*np.cos(3*X) + 4*np.cos(3*Y) - 2*np.cos(2*X - 2*Y) + 4*np.cos(3*X + 3*Y) - 2*np.cos(2*X + 4*Y) - 2*np.cos(4*X + 2*Y)): (X,Y,Z)=(rng.random()*2*np.pi-np.pi, rng.random()*2*np.pi-np.pi,rng.random()*0.12) return (X,Y)
-
Affiche la taille de T4. Tu vas constater que T4 a environ 5000 lignes quand T0 en a 3300.
En fait, $abs(sin(x) ) <0.001$ n'entraine pas $abs(sin(x) +sin(y) - sin(x+y) ) < 0.001$
Modifions un peu le code, pour voir ces lignes qui sont 'attrapées' dans T4, mais pas dans T0.
Edit : x ou y peuvent être très proches de $\pi$ ; J'ai donc corrigé la ligne v= ... ; l'ancienne version est en commentaire. Les lignes if abs() qui suivent sont également modifiées.T0 = [] T1 = [] T2 = [] T3 = [] T4 = [] n=0 while n<10000: (x,y)=SimulXY() c=0 if abs(np.sin(x)+np.sin(y)-np.sin(x+y))<0.001: n+=1 u=np.cos(x)+np.cos(y)+np.cos(x+y) T0.append(u) #v=min([abs(x), abs(y), abs(x+y) ]) v=min([abs(np.sin(x)), abs(np.sin(y)), abs(np.sin(x+y))]) #c=0 if abs( np.sin(x) )==v: T1.append(u) c+=1 if abs(np.sin(y) )==v: T2.append(u) c+=2 if abs( np.sin(x+y) )==v: T3.append(u) c+=4 if c not in [1,2,4]: print("Avertissement") print([c,(x,y,x+y,np.sin(x)+np.sin(y)-np.sin(x+y))]) if abs( np.sin(x) )<0.001: T4.append(np.cos(x)+np.cos(y)+np.cos(x+y)) if c==0 : print(x,y)
Tu me dis, j'oublie. Tu m'enseignes, je me souviens. Tu m'impliques, j'apprends. Benjamin Franklin
L'hypocrisie est pire qu'une vérité qui fait mal. Franck Ntasamara. -
Même pour des valeurs de $x$ proches de $0$, il se peut que $|\sin(x)+\sin(y) - \sin(x+y)|$ soit deux fois plus grand que $|x|$. En conséquence $|x| < \epsilon$ n'implique pas $|\sin(x) + \sin(y) - \sin(x+y)| < \epsilon$, ce qui peut créer un biais.Imaginons par exemple que $Y = D\pi - X$ avec $X$ de loi uniforme sur $[0,\pi]$ et $D$ de loi uniforme sur $\{0,1\}$, indépendante de $X$.Lorsque $\epsilon \to 0$, l'espérance de $\cos(X)+\cos(Y) + \cos(X+Y)$ tendra alors vers $\frac53$ en conditionnant par $(|\sin(X)+\sin(Y)-\sin(X+Y)| < \epsilon) \cap (|X| < \epsilon)$, tandis qu'elle tendra vers $1$ en conditionnant par $(|X| < \epsilon)$.Pour éviter ce problème, il suffirait de considérer $|X| < \frac\epsilon2$.
-
Pomme de terre : Intéressant, c'est sûrement quelque chose comme ça.J'ai fait des simulations, en ne retenant que les couples $(X,Y)$ pour lesquels $|\sin(X)+\sin(Y)-\sin(X+Y)| < 0.01$ d'une part, et j'ai refait des simulations en ne retenant que les couples $(X,Y)$ pour lesquels $|X| < 0.01$ d'autre part. Graphiquement, si on représente les couples $(X,Y)$ obtenus, ça ressemble à ça :(en bleu $|X|<0.01$, en rouge $|\sin(X)+\sin(Y)-\sin(X+Y)| < 0.01$)Si on zoome sur la bande supérieure de $X=0$, ça donne :On constate que la répartition des ordonnées n'est pas du tout la même : pour le bleu, le gros des points est entre 1.5 et 3, alors que pour le rouge, plus on monte, moins il y a de points. La loi de $Y$ sachant $|X|$ petit n'est pas du tout la même que la loi de $Y$ sachant $|\sin(X)+\sin(Y)-\sin(X+Y)|$ et $|X|$ petits.
Connectez-vous ou Inscrivez-vous pour répondre.
Bonjour!
Catégories
- 165.4K Toutes les catégories
- 63 Collège/Lycée
- 22.2K Algèbre
- 37.6K Analyse
- 6.3K Arithmétique
- 61 Catégories et structures
- 1.1K Combinatoire et Graphes
- 13 Sciences des données
- 5.1K Concours et Examens
- 23 CultureMath
- 51 Enseignement à distance
- 2.9K Fondements et Logique
- 10.8K Géométrie
- 84 Géométrie différentielle
- 1.1K Histoire des Mathématiques
- 79 Informatique théorique
- 3.9K LaTeX
- 39K Les-mathématiques
- 3.5K Livres, articles, revues, (...)
- 2.7K Logiciels pour les mathématiques
- 26 Mathématiques et finance
- 342 Mathématiques et Physique
- 5K Mathématiques et Société
- 3.3K Pédagogie, enseignement, orientation
- 10.1K Probabilités, théorie de la mesure
- 804 Shtam
- 4.2K Statistiques
- 3.8K Topologie
- 1.4K Vie du Forum et de ses membres