Tracer la distribution gaussienne en 3D

10

Dans la théorie des probabilités, la distribution normale (ou gaussienne) est une distribution de probabilité continue très courante. Les distributions normales sont importantes en statistique et sont souvent utilisées en sciences naturelles et sociales pour représenter des variables aléatoires à valeur réelle dont les distributions ne sont pas connues.

Le défi

Votre défi consiste à tracer la densité de probabilité de la distribution gaussienne sur un plan tridimensionnel . Cette fonction est définie comme:

Où:




A = 1, σ x = σ y = σ

Règles

  • Votre programme doit prendre une entrée σ , l'écart type.
  • Votre programme doit imprimer un tracé 3D de la distribution gaussienne de la plus haute qualité possible selon votre langue / système.
  • Votre programme peut ne pas utiliser une distribution gaussienne directe ou une densité de probabilité intégrée.
  • Votre programme n'a pas à se terminer.
  • Votre intrigue peut être en noir et blanc ou en couleur.
  • Votre tracé doit avoir des lignes de grille en bas. Les lignes de quadrillage sur les côtés (comme indiqué dans les exemples) ne sont pas nécessaires.
  • Votre tracé n'a pas besoin d'avoir des numéros de ligne à côté des lignes de la grille.

Notation

Comme d'habitude dans le , la soumission avec le moins d'octets gagne! Je ne pourrai jamais «accepter» une réponse à l'aide du bouton, à moins qu'elle ne soit incroyablement petite et intuitive.

Exemple de sortie

Votre sortie pourrait ressembler à ceci:

5

Ou cela pourrait ressembler à ceci:

6

Sorties plus valides . Sorties non valides .

MD XF
la source
J'étais confus que vous veniez de montrer la fonction pour l'axe X. Avons-nous besoin de prendre des entrées / sorties distinctes pour les sigma et mu X et Y?
Scott Milner
Doit-on donc supposer que μ est égal à 0? Et quelle échelle avez-vous besoin pour x et y? Si les gammes x et y sont choisies très petites par rapport à σ, le graphique ressemblera essentiellement à une fonction constante.
Greg Martin
(Pour la distribution bidimensionnelle, je pense que c'est plus clair si vous utilisez | x-μ | ^ 2 dans la définition plutôt que (x-μ) ^ 2.)
Greg Martin
@GregMartin Edited.
MD XF
2
Toujours pas clair ... que sont x_o et y_o et θ?
Greg Martin

Réponses:

7

Gnuplot 4, 64 62 61 60 47 octets

(Lié avec Mathematica ! WooHoo!)

se t pn;se is 80;sp exp(-(x**2+y**2)/(2*$0**2))

Enregistrez le code ci-dessus dans un fichier nommé A.gpet appelez-le avec ce qui suit:

gnuplot -e 'call "A.gp" $1'>GnuPlot3D.png

où le $1doit être remplacé par la valeur de σ. Cela enregistrera un .pngfichier nommé GnuPlot3D.pngcontenant la sortie souhaitée dans le répertoire de travail actuel.

Notez que cela ne fonctionne qu'avec les distributions de Gnuplot 4 car dans Gnuplot 5 les $nréférences aux arguments ont été dépréciées et remplacées par les malheureusement plus verbeuses ARGn.

Exemple de sortie avec σ = 3:

Exemple de sortie

Cette sortie est correcte selon OP .


Gnuplot 4, solution alternative, 60 octets

Voici une solution alternative qui est beaucoup plus longue que la précédente mais la sortie semble beaucoup mieux à mon avis.

se t pn;se is 80;se xyp 0;sp exp(-(x**2+y**2)/(2*$0**2))w pm

Cela nécessite toujours Gnuplot 4 pour la même raison que la solution précédente.

Exemple de sortie avec σ = 3:

Exemple de sortie n ° 2

R. Kap
la source
I am not sure if it molds to the specifications requiredà quelles spécifications pensez-vous qu'il ne répond pas?
MD XF
@MDXF Premièrement, je ne sais pas si la transparence du graphique est correcte. Honnêtement, je ne l'aime pas vraiment, c'est pourquoi je n'étais pas sûr que ce serait bien ici. Deuxièmement, le graphique commence par défaut une unité de haut en bas, et je ne suis pas sûr que ce soit bien non plus. Troisièmement, parce que le graphique commence à une unité de hauteur, je ne suis pas sûr que la disproportionnalité du graphique par rapport aux graphiques donnés dans le message d'origine soit correcte. Cependant, si tout cela vous convient, j'en ferai avec plaisir la réponse principale.
R. Kap
@MDXF En fait, j'allais l'afficher en tant que réponse d'origine, mais pour ces raisons, j'ai choisi de ne pas le faire et publié à la place par la réponse actuelle.
R. Kap
@MDXF En fait, je peux le rendre encore plus court si cela vous convient. Je comprends que ce ne sera pas le cas, mais ça ne fait pas de mal de demander. C'est la façon par défaut de Gnuplottracer la densité de probabilité de la distribution gaussienne avec un Sigma de 2sans aucune modification de l'environnement.
R. Kap
@MDXF Je suppose que j'aurais pu demander avant de poster ma réponse d'origine, mais à l'époque j'étais très impatient de poster une réponse.
R. Kap
14

C ++, 3477 3344 octets

Le nombre d'octets n'inclut pas les sauts de ligne inutiles.
MD XF a joué 133 octets.

Il n'y a aucun moyen que C ++ puisse rivaliser pour cela, mais j'ai pensé qu'il serait amusant d'écrire un logiciel de rendu pour le défi. J'ai arraché et joué à des morceaux de GLM pour les mathématiques 3D et j'ai utilisé l'algorithme de ligne de Xiaolin Wu pour la pixellisation. Le programme envoie le résultat dans un fichier PGM nommé g.

Production

#include<array>
#include<cmath>
#include<vector>
#include<string>
#include<fstream>
#include<algorithm>
#include<functional>
#define L for
#define A auto
#define E swap
#define F float
#define U using
U namespace std;
#define K vector
#define N <<"\n"
#define Z size_t
#define R return
#define B uint8_t
#define I uint32_t
#define P operator
#define W(V)<<V<<' '
#define Y template<Z C>
#define G(O)Y vc<C>P O(vc<C>v,F s){vc<C>o;L(Z i=0;i<C;++i){o\
[i]=v[i]O s;}R o;}Y vc<C>P O(vc<C>l, vc<C>r){vc<C>o;L(Z i=0;i<C;++i){o[i]=l[i]O r[i];}R o;}
Y U vc=array<F,C>;U v2=vc<2>;U v3=vc<3>;U v4=vc<4>;U m4=array<v4,4>;G(+)G(-)G(*)G(/)Y F d(
vc<C>a,vc<C>b){F o=0;L(Z i=0;i<C;++i){o+=a[i]*b[i];}R o;}Y vc<C>n(vc<C>v){R v/sqrt(d(v,v));
}v3 cr(v3 a,v3 b){R v3{a[1]*b[2]-b[1]*a[2],a[2]*b[0]-b[2]*a[0],a[0]*b[1]-b[0]*a[1]};}m4 P*(
m4 l,m4 r){R{l[0]*r[0][0]+l[1]*r[0][1]+l[2]*r[0][2]+l[3]*r[0][3],l[0]*r[1][0]+l[1]*r[1][1]+
l[2]*r[1][2]+l[3]*r[1][3],l[0]*r[2][0]+l[1]*r[2][1]+l[2]*r[2][2]+l[3]*r[2][3],l[0]*r[3][0]+
l[1]*r[3][1]+l[2]*r[3][2]+l[3]*r[3][3]};}v4 P*(m4 m,v4 v){R v4{m[0][0]*v[0]+m[1][0]*v[1]+m[
2][0]*v[2]+m[3][0]*v[3],m[0][1]*v[0]+m[1][1]*v[1]+m[2][1]*v[2]+m[3][1]*v[3],m[0][2]*v[0]+m[
1][2]*v[1]+m[2][2]*v[2]+m[3][2]*v[3],m[0][3]*v[0]+m[1][3]*v[1]+m[2][3]*v[2]+m[3][3]*v[3]};}
m4 at(v3 a,v3 b,v3 c){A f=n(b-a);A s=n(cr(f,c));A u=cr(s,f);A o=m4{1,0,0,0,0,1,0,0,0,0,1,0,
0,0,0,1};o[0][0]=s[0];o[1][0]=s[1];o[2][0]=s[2];o[0][1]=u[0];o[1][1]=u[1];o[2][1]=u[2];o[0]
[2]=-f[0];o[1][2]=-f[1];o[2][2]=-f[2];o[3][0]=-d(s,a);o[3][1]=-d(u,a);o[3][2]=d(f,a);R o;}
m4 pr(F f,F a,F b,F c){F t=tan(f*.5f);m4 o{};o[0][0]=1.f/(t*a);o[1][1]=1.f/t;o[2][3]=-1;o[2
][2]=c/(b-c);o[3][2]=-(c*b)/(c-b);R o;}F lr(F a,F b,F t){R fma(t,b,fma(-t,a,a));}F fp(F f){
R f<0?1-(f-floor(f)):f-floor(f);}F rf(F f){R 1-fp(f);}struct S{I w,h; K<F> f;S(I w,I h):w{w
},h{h},f(w*h){}F&P[](pair<I,I>c){static F z;z=0;Z i=c.first*w+c.second;R i<f.size()?f[i]:z;
}F*b(){R f.data();}Y vc<C>n(vc<C>v){v[0]=lr((F)w*.5f,(F)w,v[0]);v[1]=lr((F)h*.5f,(F)h,-v[1]
);R v;}};I xe(S&f,v2 v,bool s,F g,F c,F*q=0){I p=(I)round(v[0]);A ye=v[1]+g*(p-v[0]);A xd=
rf(v[0]+.5f);A x=p;A y=(I)ye;(s?f[{y,x}]:f[{x,y}])+=(rf(ye)*xd)*c;(s?f[{y+1,x}]:f[{x,y+1}])
+=(fp(ye)*xd)*c;if(q){*q=ye+g;}R x;}K<v4> g(F i,I r,function<v4(F,F)>f){K<v4>g;F p=i*.5f;F
q=1.f/r;L(Z zi=0;zi<r;++zi){F z=lr(-p,p,zi*q);L(Z h=0;h<r;++h){F x=lr(-p,p,h*q);g.push_back
(f(x,z));}}R g;}B xw(S&f,v2 b,v2 e,F c){E(b[0],b[1]);E(e[0],e[1]);A s=abs(e[1]-b[1])>abs
(e[0]-b[0]);if(s){E(b[0],b[1]);E(e[0],e[1]);}if(b[0]>e[0]){E(b[0],e[0]);E(b[1],e[1]);}F yi=
0;A d=e-b;A g=d[0]?d[1]/d[0]:1;A xB=xe(f,b,s,g,c,&yi);A xE=xe(f,e,s,g,c);L(I x=xB+1;x<xE;++
x){(s?f[{(I)yi,x}]:f[{x,(I)yi}])+=rf(yi)*c;(s?f[{(I)yi+1,x}]:f[{x,(I)yi+1}])+=fp(yi)*c;yi+=
g;}}v4 tp(S&s,m4 m,v4 v){v=m*v;R s.n(v/v[3]);}main(){F l=6;Z c=64;A J=g(l,c,[](F x,F z){R
v4{x,exp(-(pow(x,2)+pow(z,2))/(2*pow(0.75f,2))),z,1};});I w=1024;I h=w;S s(w,h);m4 m=pr(
1.0472f,(F)w/(F)h,3.5f,11.4f)*at({4.8f,3,4.8f},{0,0,0},{0,1,0});L(Z j=0;j<c;++j){L(Z i=0;i<
c;++i){Z id=j*c+i;A p=tp(s,m,J[id]);A dp=[&](Z o){A e=tp(s,m,J[id+o]);F v=(p[2]+e[2])*0.5f;
xw(s,{p[0],p[1]},{e[0],e[1]},1.f-v);};if(i<c-1){dp(1);}if(j<c-1){dp(c);}}}K<B> b(w*h);L(Z i
=0;i<b.size();++i){b[i]=(B)round((1-min(max(s.b()[i],0.f),1.f))*255);}ofstream f("g");f 
W("P2")N;f W(w)W(h)N;f W(255)N;L(I y=0;y<h;++y){L(I x=0;x<w;++x)f W((I)b[y*w+x]);f N;}R 0;}
  • l est la longueur d'un côté de la grille dans l'espace mondial.
  • c est le nombre de sommets le long de chaque bord de la grille.
  • La fonction qui crée la grille est appelée avec une fonction qui prend deux entrées, les coordonnées spatiales mondiales du sommet xet z(et y augmente) et renvoie la position spatiale mondiale du sommet.
  • w est la largeur du pgm
  • h est la hauteur du pgm
  • mest la matrice de vue / projection. Les arguments utilisés pour créer msont ...
    • champ de vision en radians
    • rapport d'aspect du pgm
    • près du plan du clip
    • plan de clip lointain
    • position de la caméra
    • cible de la caméra
    • le vecteur

Le moteur de rendu pourrait facilement avoir plus de fonctionnalités, de meilleures performances et être mieux joué, mais je me suis bien amusé!

Patrick Purcell
la source
2
Wow, c'est incroyable!
MD XF
1
Pas du tout ... allez-y!
Patrick Purcell
1
Voilà, 133 octets de moins!
MD XF
1
C'est formidable! Si vous pouviez me dire où vous avez appris tout cela, ce serait formidable !
HatsuPointerKun du
1
@HatsuPointerKun Heureux que vous l'appréciez! Ce tutoriel ... opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices ... est un excellent point de départ.
Patrick Purcell
9

Mathematica, 47 octets

Plot3D[E^(-(x^2+y^2)/2/#^2),{x,-6,6},{y,-6,6}]&

prend en entrée σ

Contribution

[2]

production
entrez la description de l'image ici

-2 octets grâce à LLlAMnYP

J42161217
la source
1
Mathematica gagne? Pas de surprise là-bas: P
MD XF
3
Enregistrement de 2 octets avecE^(-(x^2+y^2)/2/#^2)
LLlAMnYP
6

R, 105 102 87 86 octets

s=scan();plot3D::persp3D(z=sapply(x<-seq(-6,6,.1),function(y)exp(-(y^2+x^2)/(2*s^2))))

Prend Sigma de STDIN. Crée un vecteur de -6à 6par étapes de .1pour les deux xet y, puis crée une 121x121matrice en prenant le produit externe de xet y. C'est plus court que d'appeler matrixet de spécifier les dimensions. La matrice est maintenant déjà remplie, mais ce n'est pas grave, car nous l'écrasons.

La forboucle en boucle sur les valeurs de x, en utilisant les opérations vectorisées dans R, créant la matrice de densité une ligne à la fois.

(s)applyest encore une méthode plus courte pour les opérations vectorisées. Comme le héros qu'il est, il gère lui-même la création de la matrice, économisant pas mal d'octets.

entrez la description de l'image ici

128 125 110 109 octets, mais beaucoup plus sophistiqué:

Ce tracé est créé par le plotlypackage. Malheureusement, la spécification est un peu verbeuse, donc cela coûte beaucoup d'octets. Mais le résultat est vraiment très chic. Je recommanderais fortement de l'essayer par vous-même.

s=scan();plotly::plot_ly(z=sapply(x<-seq(-6,6,.1),function(y)exp(-(y^2+x^2)/(2*s^2))),x=x,y=x,type="surface")

bla

JAD
la source
J'ai précisé dans la question que le graphique n'a pas besoin d'avoir des numéros de ligne, votre deuxième soumission est très bien.
MD XF
Oh, j'ai dû manquer ça. J'ai échangé mes solutions. Je pense que l' plotlyintrigue est suffisamment sophistiquée pour mériter d'être incluse ici.
JAD
Eh bien, les deux sont beaucoup plus fantaisistes que les miens : P
MD XF
Puisque vous ne l'utilisez squ'une seule fois, pourriez-vous faire 2*scan()^2et supprimer le s=scan();au début? Cela économiserait 3 octets.
KSmarts
6

Applesoft BASIC, 930 783 782 727 719 702 695 637 octets

-72 octets et un programme de travail grâce à plafondcat repérant mon erreur et un algorithme raccourci

0TEXT:HOME:INPUTN:HGR:HCOLOR=3:W=279:H=159:L=W-100:Z=L/10:B=H-100:C=H-60:K=0.5:M=1/(2*3.14159265*N*N):FORI=0TO10STEPK:X=10*I+1:Y=10*I+B:HPLOTX,Y:FORJ=0TOL STEP1:O=10*J/L:D=ABS(5-I):E=ABS(5-O):R=(D*D+E*E)/(2*N*N):G=EXP(-R)*M:A=INT((C*G)/M):X=10*I+Z*O+1:Y=10*I+B-A:HPLOTTOX,Y:IF(I=0)GOTO4
1IF(J=L)GOTO3
2V=INT(J/10):IF((J/10)<>V)GOTO5
3D=ABS(5-I+K):E=ABS(5-O):R=(D*D+E*E)/(2*N*N):U=EXP(-R)/(2*3.14159*N*N):S=INT((C*U)/M):P=10*(I-K)+Z*O+1:Q=10*(I-K)+B-S:HPLOT TOP,Q:HPLOTX,Y
4IF(J=0)GOTO7:IF(I<10)GOTO5:IF(J=L)GOTO6:V=INT(J/10):IF((J/10)=V)GOTO6
5HCOLOR=0
6HPLOTTOX,10*I+B:HCOLOR=3:HPLOTX,Y
7NEXTJ:NEXTI:HPLOTW+1,H:HPLOTTO101,H:HPLOTTO0+1,H

Version non golfée ici.

Lorsqu'une entrée est donnée 1:

entrée-1

Lorsqu'une entrée est donnée 2:

entrée-2

MD XF
la source
1
Cela montre encore une fois la supériorité de BASIC ....
Peut économiser quelques octets supplémentaires en définissant une ou plusieurs variables sur une valeur fréquemment utilisée, telle que 10. De plus, nous vous suggérons de remplacer EXP(X)/(2*3.14159*S1*S1)parEXP(X)*M
plafondcat