Plot Distribusi Gaussian dalam 3D

10

Dalam teori probabilitas, distribusi normal (atau Gaussian) adalah distribusi probabilitas kontinu yang sangat umum. Distribusi normal penting dalam statistik dan sering digunakan dalam ilmu alam dan sosial untuk mewakili variabel acak bernilai nyata yang distribusinya tidak diketahui.

Tantangan

Tantangan Anda adalah memplot kerapatan probabilitas Distribusi Gaussian pada bidang 3 dimensi . Fungsi ini didefinisikan sebagai:

Dimana:




A = 1, σ x = σ y = σ

Aturan

  • Program Anda harus mengambil satu input σ , standar deviasi.
  • Program Anda harus mencetak plot 3D Distribusi Gaussian dengan kualitas terbaik sesuai bahasa / sistem Anda.
  • Program Anda tidak boleh menggunakan Distribusi Gaussian langsung atau tingkat kemungkinan kepadatan.
  • Program Anda tidak harus berakhir.
  • Plot Anda mungkin hitam putih atau berwarna.
  • Plot Anda harus memiliki garis kisi di bagian bawah. Garis kisi di sisi (seperti yang ditunjukkan dalam contoh) tidak perlu.
  • Plot Anda tidak perlu memiliki nomor baris di sebelah garis kisi.

Mencetak gol

Seperti biasa dalam , pengajuan dengan byte terkecil menang! Saya mungkin tidak pernah "menerima" jawaban menggunakan tombol, kecuali ada yang sangat kecil dan intuitif.

Contoh output

Output Anda dapat terlihat seperti ini:

5

Atau bisa terlihat seperti ini:

6

Lebih banyak keluaran yang valid . Output tidak valid .

MD XF
sumber
Saya bingung bahwa Anda baru saja menunjukkan fungsi untuk sumbu X. Apakah kita perlu mengambil input / output terpisah untuk sigma X dan Y dan mu?
Scott Milner
Jadi apakah kita berasumsi bahwa μ sama dengan 0? Dan skala apa yang Anda butuhkan untuk x dan y? Jika rentang x dan y dipilih sangat kecil relatif terhadap σ, maka grafik pada dasarnya akan terlihat seperti fungsi konstan.
Greg Martin
(Untuk distribusi dua dimensi, saya pikir lebih jelas jika Anda menggunakan | x-μ | ^ 2 dalam definisi daripada (x-μ) ^ 2.)
Greg Martin
@GregMartin Diedit.
MD XF
2
Masih tidak jelas ... apa itu x_o dan y_o dan θ?
Greg Martin

Jawaban:

7

Gnuplot 4, 64 62 61 60 47 byte

(Terikat dengan Mathematica ! WooHoo!)

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

Simpan kode di atas ke dalam file bernama A.gpdan jalankan dengan yang berikut ini:

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

di mana $1harus diganti dengan nilai σ. Ini akan menyimpan .pngfile bernama GnuPlot3D.pngberisi output yang diinginkan ke direktori kerja saat ini.

Perhatikan bahwa ini hanya berfungsi dengan distribusi Gnuplot 4 karena dalam Gnuplot 5 $nreferensi ke argumen sudah tidak digunakan lagi dan diganti dengan yang sayangnya lebih bertele-tele ARGn.

Output sampel dengan σ = 3:

Output Sampel

Output ini baik-baik saja menurut OP .


Gnuplot 4, Solusi Alternatif, 60 byte

Berikut ini adalah solusi alternatif yang jauh lebih lama dari yang sebelumnya tetapi hasilnya terlihat jauh lebih baik menurut saya.

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

Ini masih membutuhkan Gnuplot 4 untuk alasan yang sama dengan solusi sebelumnya.

Output sampel dengan σ = 3:

Contoh Output # 2

R. Kap
sumber
I am not sure if it molds to the specifications requiredspesifikasi apa yang menurut Anda tidak memenuhi?
MD XF
@ MDXF Pertama, saya tidak yakin apakah transparansi grafik baik-baik saja. Sejujurnya aku tidak begitu suka, itu sebabnya aku tidak yakin apakah itu akan baik-baik saja di sini. Kedua, grafik dimulai satu unit tinggi dari bawah secara default, dan saya tidak yakin apakah itu baik-baik saja. Ketiga, karena grafik dimulai dengan tinggi satu unit, saya tidak yakin ketidakseimbangan grafik dibandingkan dengan grafik yang diberikan dalam posting asli tidak apa-apa. Namun, jika ini semua baik-baik saja dengan Anda, saya akan dengan senang hati menjadikannya jawaban utama.
R. Kap
@MDXF Sebenarnya, saya akan mempostingnya sebagai jawaban asli, tetapi untuk alasan ini saya memilih untuk tidak dan memposting dengan jawaban saat ini sebagai gantinya.
R. Kap
@ MDXF Sebenarnya, saya bisa membuatnya lebih pendek jika ini oke. Saya mengerti jika itu tidak akan terjadi, tetapi tidak ada salahnya untuk bertanya. Ini adalah cara standar Gnuplotakan memplot kepadatan probabilitas distribusi Gaussian dengan Sigma 2tanpa modifikasi lingkungan.
R. Kap
@ MDXF Saya kira saya bisa bertanya sebelum memposting jawaban asli saya, tetapi pada saat itu saya sangat ingin mengirim jawaban.
R. Kap
14

C ++, 3477 3344 bytes

Hitungan byte tidak termasuk baris baru yang tidak perlu.
MD XF bermain golf 133 byte.

Tidak mungkin C ++ dapat bersaing untuk ini, tetapi saya pikir akan menyenangkan untuk menulis perender perangkat lunak untuk tantangan ini. Saya merobek dan memutarkan beberapa potongan GLM untuk matematika 3D dan menggunakan algoritma garis Xiaolin Wu untuk rasterisasi. Program menampilkan hasilnya ke file PGM bernama g.

Keluaran

#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 adalah panjang satu sisi grid di ruang dunia.
  • c adalah jumlah simpul di sepanjang setiap tepi grid.
  • Fungsi yang membuat kisi disebut dengan fungsi yang mengambil dua input, koordinat ruang dunia xdan z(+ y naik) dari titik, dan mengembalikan posisi ruang dunia dari titik.
  • w adalah lebar pgm
  • h adalah ketinggian pgm
  • madalah view / projection matrix. Argumen yang digunakan untuk membuat madalah ...
    • bidang pandang dalam radian
    • rasio aspek pgm
    • dekat pesawat klip
    • pesawat klip jauh
    • posisi kamera
    • target kamera
    • vektor atas

Penyaji dapat dengan mudah memiliki lebih banyak fitur, kinerja yang lebih baik, dan bermain golf yang lebih baik, tetapi saya bersenang-senang!

Patrick Purcell
sumber
2
Wow, itu luar biasa!
MD XF
1
Sama sekali tidak ... lakukanlah!
Patrick Purcell
1
Ini dia, 133 byte!
MD XF
1
Ini luar biasa! Jika Anda bisa memberi tahu saya di mana Anda mempelajari semua itu, itu akan bagus !
HatsuPointerKun
1
@HatsuPointerKun Senang Anda menikmatinya! Tutorial ini ... opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices ... adalah tempat yang bagus untuk memulai.
Patrick Purcell
9

Mathematica, 47 byte

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

mengambil input σ

Memasukkan

[2]

keluaran
masukkan deskripsi gambar di sini

-2 byte terima kasih kepada LLlAMnYP

J42161217
sumber
1
Matematika menang? Tidak ada kejutan di sana: P
MD XF
3
Menyimpan 2 byte denganE^(-(x^2+y^2)/2/#^2)
LLlAMnYP
6

R, 105 102 87 86 byte

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

Membawa Sigma dari STDIN. Membuat vektor dari -6ke 6dalam langkah-langkah .1untuk keduanya xdan y, kemudian membuat 121x121matriks dengan mengambil produk luar xdan y. Ini lebih pendek daripada memanggil matrixdan menentukan dimensi. Matriks sekarang sudah diisi, tapi tidak apa-apa, karena kita menimpanya.

The forloop -loop atas nilai-nilai dalam x, memanfaatkan operasi Vectorized di R, menciptakan kepadatan matriks satu baris pada suatu waktu.

(s)applylagi adalah metode yang lebih pendek untuk operasi vektor. Seperti pahlawannya, ia menangani pembuatan matriks dengan sendirinya, menghemat beberapa byte.

masukkan deskripsi gambar di sini

128 125 110 109 byte, tetapi jauh lebih mewah:

Plot ini dibuat oleh plotlypaket. Sayangnya spesifikasi agak bertele-tele, jadi ini biaya banyak byte. Hasilnya sungguh sangat mewah. Saya sangat merekomendasikan untuk mencobanya sendiri.

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
sumber
Saya menentukan dalam pertanyaan bahwa grafik tidak perlu memiliki nomor baris, pengiriman kedua Anda baik-baik saja.
MD XF
Oh, aku pasti melewatkan itu. Saya bertukar solusi saya di sekitar. Saya pikir plotlyplotnya cukup mewah untuk menjamin masih dimasukkan di sini.
JAD
Ya, keduanya jauh lebih keren dari saya : P
MD XF
Karena Anda hanya menggunakan ssekali, dapatkah Anda melakukan 2*scan()^2dan menghapus s=scan();di awal? Ini akan menghemat 3 byte.
KSmarts
6

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

-72 byte dan program kerja berkat ceilingcat melihat kesalahan saya dan algoritma yang dipersingkat

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

Versi tidak dikolomasikan di sini.

Saat diberi input 1:

input-1

Saat diberi input 2:

input-2

MD XF
sumber
1
Ini lagi-lagi menunjukkan keunggulan BASIC ....
Dapat menyimpan beberapa byte lagi dengan menetapkan satu atau lebih variabel ke beberapa nilai yang sering digunakan, seperti 10. Juga, sarankan untuk mengganti EXP(X)/(2*3.14159*S1*S1)denganEXP(X)*M
ceilingcat