Vẽ sơ đồ phân phối Gaussian trong 3D


10

Trong lý thuyết xác suất, phân phối bình thường (hoặc Gaussian) là phân phối xác suất liên tục rất phổ biến. Phân phối bình thường rất quan trọng trong thống kê và thường được sử dụng trong khoa học tự nhiên và xã hội để biểu diễn các biến ngẫu nhiên có giá trị thực mà phân phối không được biết đến.

Các thách thức

Thách thức của bạn là vẽ mật độ xác suất của Phân phối Gaussian trên mặt phẳng 3 chiều . Hàm này được định nghĩa là:

Ở đâu:




Một = 1, σ x = σ y = σ

Quy tắc

  • Chương trình của bạn phải mất một đầu vào σ , độ lệch chuẩn.
  • Chương trình của bạn phải in một bản đồ 3D của Phân phối Gaussian với chất lượng cao nhất như ngôn ngữ / hệ thống của bạn cho phép.
  • Chương trình của bạn không được sử dụng phân phối Gaussian trực tiếp hoặc mật độ xác suất tích hợp.
  • Chương trình của bạn không phải chấm dứt.
  • Âm mưu của bạn có thể là màu đen và trắng hoặc màu.
  • Âm mưu của bạn phải có các đường lưới ở phía dưới. Các đường lưới ở hai bên (như trong ví dụ) là không cần thiết.
  • Âm mưu của bạn không cần phải có số dòng bên cạnh các đường lưới.

Chấm điểm

Như thường lệ trong , bài nộp có ít byte nhất sẽ thắng! Tôi có thể không bao giờ "chấp nhận" một câu trả lời bằng nút này, trừ khi nó cực kỳ nhỏ và trực quan.

Ví dụ đầu ra

Đầu ra của bạn có thể trông giống như thế này:

5

Hoặc nó có thể trông như thế này:

6

Đầu ra hợp lệ hơn . Đầu ra không hợp lệ .


Tôi đã nhầm lẫn rằng bạn chỉ hiển thị chức năng cho trục X. Chúng ta có cần lấy đầu vào / đầu ra riêng biệt cho sigma X và Y và mu không?
Scott Milner

Vậy chúng ta có giả sử rằng bằng 0 không? Và quy mô nào bạn yêu cầu cho x và y? Nếu phạm vi x và y được chọn rất nhỏ so với, thì về cơ bản biểu đồ sẽ trông giống như một hàm hằng.
Greg Martin

(Đối với phân phối hai chiều, tôi nghĩ sẽ rõ ràng hơn nếu bạn sử dụng | x-μ | ^ 2 trong định nghĩa thay vì (x-μ) ^ 2.)
Greg Martin

@GregMartin Đã chỉnh sửa.
MD XF

2
Vẫn chưa rõ ... x_o và y_o và là gì?
Greg Martin

Câu trả lời:


7

Gnuplot 4, 64 62 61 60 47 byte

(Tied với Mathematica ! WooHoo!)

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

Lưu mã ở trên vào một tệp có tên A.gpvà gọi nó bằng cách sau:

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

trong đó $1được thay thế bằng giá trị của σ. Điều này sẽ lưu một .pngtệp có tên GnuPlot3D.pngchứa đầu ra mong muốn vào thư mục làm việc hiện tại.

Lưu ý rằng điều này chỉ hoạt động với các bản phân phối của Gnuplot 4 vì trong Gnuplot 5, các $ntham chiếu đến các đối số không được dùng nữa và được thay thế bằng phần dài hơn không may ARGn.

Đầu ra mẫu với σ = 3:

Đầu ra mẫu

Đầu ra này là tốt theo OP .


Gnuplot 4, Giải pháp thay thế, 60 byte

Đây là một giải pháp thay thế dài hơn nhiều so với giải pháp trước nhưng theo tôi thì đầu ra có vẻ tốt hơn nhiều.

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

Điều này vẫn yêu cầu Gnuplot 4 vì lý do tương tự như giải pháp trước đó.

Đầu ra mẫu với σ = 3:

Kết quả mẫu số 2


I am not sure if it molds to the specifications requiredNhững thông số kỹ thuật nào bạn nghĩ rằng nó không đáp ứng?
MD XF

@MDXF Thứ nhất, tôi không chắc liệu độ trong suốt của đồ thị có ổn không. Tôi thực sự không thích nó, đó là lý do tại sao tôi không chắc liệu nó có ổn ở đây không. Thứ hai, biểu đồ bắt đầu một đơn vị cao từ dưới lên theo mặc định và tôi không chắc liệu điều đó có ổn không. Thứ ba, vì biểu đồ bắt đầu cao một đơn vị, tôi không chắc sự không tương xứng của biểu đồ so với các biểu đồ được đưa ra trong bài viết gốc là ổn. Tuy nhiên, nếu tất cả đều ổn với bạn, tôi sẽ vui vẻ biến nó thành câu trả lời chính.
R. Kap

@MDXF Trên thực tế, tôi sẽ đăng nó dưới dạng câu trả lời ban đầu, nhưng vì những lý do này, tôi đã chọn không đăng và thay vào đó bằng câu trả lời hiện tại.
R. Kap

@MDXF Trên thực tế, tôi có thể làm cho nó thậm chí ngắn hơn nếu điều này là ổn. Tôi hiểu nếu nó sẽ không, nhưng nó không đau để hỏi. Đây là cách mặc định Gnuplotsẽ vẽ mật độ xác suất của phân phối Gaussian với Sigma 2mà không có bất kỳ sửa đổi môi trường nào.
R. Kap

@MDXF Tôi đoán tôi có thể đã hỏi trước khi đăng câu trả lời ban đầu của mình, nhưng tại thời điểm đó tôi rất háo hức đăng câu trả lời.
R. Kap

14

C ++, 3477 3344 byte

Số lượng byte không bao gồm các dòng mới không cần thiết.
MD XF đã đánh bại 133 byte.

Không có cách nào C ++ có thể cạnh tranh cho điều này, nhưng tôi nghĩ sẽ rất vui khi viết một trình kết xuất phần mềm cho thử thách. Tôi đã xé và chơi một số khối GLM cho toán học 3D và sử dụng thuật toán dòng của Xiaolin Wu để rasterization. Chương trình xuất kết quả ra tệp PGM có tên g.

Đầu ra

#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 là chiều dài của một bên của lưới trong không gian thế giới.
  • c là số đỉnh dọc theo mỗi cạnh của lưới.
  • Hàm tạo lưới được gọi với hàm có hai đầu vào, xz(+ y đi lên) tọa độ không gian thế giới của đỉnh và trả về vị trí không gian thế giới của đỉnh.
  • w là chiều rộng của pgm
  • h là chiều cao của pgm
  • mlà ma trận xem / chiếu. Các đối số được sử dụng để tạo mlà ...
    • lĩnh vực xem trong radian
    • tỷ lệ khung hình của pgm
    • gần máy bay clip
    • máy bay clip xa
    • vị trí camera
    • mục tiêu máy ảnh
    • lên vector

Trình kết xuất có thể dễ dàng có nhiều tính năng hơn, hiệu suất tốt hơn và được chơi golf tốt hơn, nhưng tôi đã có niềm vui của mình!


2
Wow, thật không thể tin được!
MD XF

1
Không hề ... đi cho nó!
Patrick Purcell

1
Có bạn đi, tắt 133 byte!
MD XF

1
Điều này thật tuyệt vời! Nếu bạn có thể cho tôi biết nơi bạn học được tất cả những điều đó, điều đó sẽ rất tuyệt !
HatsuPulumKun

1
@HatsuPulumKun Vui mừng bạn thích nó! Hướng dẫn này ... opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices ... là một nơi tuyệt vời để bắt đầu.
Patrick Purcell

9

Toán học, 47 byte

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

lấy làm đầu vào

Đầu vào

[2]

đầu ra
nhập mô tả hình ảnh ở đây

-2 byte nhờ LLlAMnYP


1
Toán học chiến thắng? Không có gì ngạc nhiên ở đó: P
MD XF

3
Lưu 2 byte vớiE^(-(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))))

Mất Sigma từ STDIN. Tạo một vector từ -6để 6trong các bước của .1cho cả hai xy, sau đó tạo ra một 121x121ma trận bằng cách lấy sản phẩm ngoài của xy. Điều này ngắn hơn so với gọi matrixvà chỉ định kích thước. Ma trận hiện đã được điền, nhưng không sao, vì chúng ta đang ghi đè lên nó.

Các forvòng lặp -loop trên các giá trị trong x, sử dụng các hoạt động được vector hóa trong R, tạo ra ma trận mật độ một hàng tại một thời điểm.

(s)applymột lần nữa là một phương pháp ngắn hơn cho các hoạt động vector hóa. Giống như anh hùng, nó tự xử lý việc tạo ra ma trận, tiết kiệm khá nhiều byte.

nhập mô tả hình ảnh ở đây

128 125 110 109 byte, nhưng cách lạ mắt hơn:

Âm mưu này được tạo ra bởi plotlygói. Đáng buồn là đặc tả hơi dài dòng, vì vậy điều này tốn rất nhiều byte. Kết quả là thực sự thực sự ưa thích mặc dù. Tôi rất khuyên bạn nên thử nó cho chính mình.

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


Tôi đã chỉ định trong câu hỏi rằng đồ thị không cần phải có số dòng, lần gửi thứ hai của bạn vẫn ổn.
MD XF

Ồ, tôi đã phải bỏ lỡ điều đó. Tôi trao đổi các giải pháp của tôi xung quanh. Tôi nghĩ rằng plotlycốt truyện là đủ lạ mắt để đảm bảo vẫn được đưa vào đây.
JAD

Chà, cả hai đều nhiều, huyền ảo hơn tôi : P
MD XF

Vì bạn chỉ sử dụng smột lần, bạn có thể làm 2*scan()^2và loại bỏ s=scan();khi bắt đầu không? Nó sẽ tiết kiệm 3 byte.
KSmarts

6

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

-72 byte và một chương trình hoạt động nhờ trần nhà phát hiện lỗi của tôi và thuật toán rút ngắn

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

Phiên bản Ungolfed ở đây.

Khi cho đầu vào 1:

đầu vào-1

Khi cho đầu vào 2:

đầu vào-2


1
Điều này một lần nữa cho thấy sự vượt trội của BASIC ....

Có thể lưu thêm một vài byte bằng cách đặt một hoặc nhiều biến thành một số giá trị được sử dụng thường xuyên, chẳng hạn như 10. Ngoài ra, đề nghị thay thế EXP(X)/(2*3.14159*S1*S1)bằngEXP(X)*M
trần nhà
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.