3D로 가우스 분포를 플로팅


10

확률 이론에서 정규 (또는 가우시안) 분포 는 매우 일반적인 연속 확률 분포입니다. 정규 분포는 통계에서 중요하며 분포가 알려지지 않은 실제 값의 랜덤 변수를 나타 내기 위해 자연 및 사회 과학에서 종종 사용됩니다.

도전

문제는 3 차원 평면 에서 가우스 분포 의 확률 밀도 를 플로팅하는 것 입니다. 이 기능은 다음과 같이 정의됩니다.

어디:




A = 1, σ x = σ y = σ

규칙

  • 프로그램은 표준 편차 인 하나의 입력 σ를 가져야합니다 .
  • 프로그램은 언어 / 시스템이 허용하는 한 최고 품질로 가우시안 분포의 3D 플롯을 인쇄해야합니다.
  • 프로그램이 직접 가우스 분포 또는 확률 밀도 내장을 사용하지 않을 수 있습니다.
  • 프로그램을 종료하지 않아도됩니다.
  • 플롯은 흑백 또는 컬러 일 수 있습니다.
  • 플롯의 맨 아래에 그리드 선이 있어야합니다. 측면의 그리드 선 (예에 표시됨)은 필요하지 않습니다.
  • 플롯에는 그리드 선 옆에 선 번호가 없어도됩니다.

채점

에서 평소와 같이 , 최소한의 함께 제출 승 바이트! 매우 작고 직관적 인 경우를 제외하고는 버튼을 사용하여 답변을 "수락"할 수 없습니다.

출력 예

출력 결과는 다음과 같습니다.

5

또는 다음과 같이 보일 수 있습니다.

6

유효한 출력 . 잘못된 출력 입니다.


X 축에 대한 기능을 방금 표시 한 것이 혼란 스러웠습니다. X 및 Y 시그마 및 mu에 대해 별도의 입력 / 출력을 취해야합니까?
Scott Milner

따라서 μ가 0과 같다고 가정합니까? 그리고 x와 y에 어떤 규모가 필요합니까? x 및 y 범위가 σ에 비해 매우 작게 선택되면 그래프는 본질적으로 상수 함수처럼 보입니다.
Greg Martin

(2 차원 분포의 경우 (x-μ) ^ 2가 아닌 정의에서 | x-μ | ^ 2를 사용하면 더 명확하다고 생각합니다.)
Greg Martin

@GregMartin 편집했습니다.
MD XF

2
여전히 명확하지 않습니다 ... x_o 및 y_o 및 θ는 무엇입니까?
Greg Martin

답변:


7

그노 플롯 4, 64 62 61 60 47 바이트

( Mathematica 와 연결 ! 우후!)

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

위의 코드를 파일 이름으로 저장하고 A.gp다음을 사용하여 호출하십시오.

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

여기서는의 $1값으로 대체됩니다 σ. 원하는 출력이 포함 된 .png파일 GnuPlot3D.png이 현재 작업 디렉토리에 저장됩니다.

이 있습니다 의 gnuplot 5 이후의 gnuplot 4의 분포와 작품이 $n인수에 대한 참조가되지 않는 더 장황 불행하게도로 대체되었다 ARGn.

를 사용한 샘플 출력 σ = 3:

샘플 출력

이 출력은 OP 에 따라 정상 입니다.


Gnuplot 4, 대체 솔루션, 60 바이트

다음은 이전 솔루션보다 훨씬 긴 대체 솔루션이지만 내 의견으로는 출력이 훨씬 나아 보입니다.

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

이전 솔루션과 동일한 이유로 여전히 Gnuplot 4가 필요합니다.

를 사용한 샘플 출력 σ = 3:

샘플 출력 # 2


I am not sure if it molds to the specifications required어떤 사양에 맞지 않는다고 생각하십니까?
MD XF

@MDXF 첫째, 그래프의 투명도가 올바른지 확실하지 않습니다. 솔직히 마음에 들지 않기 때문에 여기에서 잘 될지 확신 할 수 없습니다. 둘째, 그래프는 기본적으로 바닥에서 한 단위 높이 시작합니다. 셋째, 그래프가 한 단위 높이 시작하기 때문에 원래 게시물에 제공된 그래프와 비교하여 그래프의 불균형이 확실하지 않습니다. 그러나 이것이 모두 당신에게 괜찮다면, 나는 그것을 행복하게 주요 답변으로 삼을 것입니다.
R. Kap

@MDXF 사실, 나는 그것을 원래의 답변으로 게시하려고했지만 이러한 이유로 나는 현재 답변을 선택하지 않고 게시했습니다.
R. Kap

@MDXF 사실, 이것이 괜찮다 면 더 짧게 만들 수 있습니다 . 나는 그것이 아닌지 이해하지만 물어 보는 것이 아프지 않습니다. 환경 수정없이 Gnuplot시그마를 사용하여 가우스 분포의 확률 밀도를 플로팅하는 것이 기본 방법 입니다 2.
R. Kap

@ MDXF 나는 원래 답변을 게시하기 전에 요청할 수 있었지만 그 당시에는 답변을 게시하기를 열망했습니다.
R. Kap

14

C ++, 3477 3344 바이트

바이트 수에는 불필요한 줄 바꿈이 포함되지 않습니다.
MD XF는 133 바이트를 떨어 뜨렸다.

C ++이이를 위해 경쟁 할 수있는 방법은 없지만, 난제를 위해 소프트웨어 렌더러를 작성하는 것이 재미있을 것이라고 생각했습니다. 나는 3D 수학을 위해 GLM 덩어리를 찢어 버렸고 래스터 화를 위해 Xiaolin Wu의 라인 알고리즘사용 했습니다. 프로그램은 이름이 PGM 파일로 결과를 출력합니다 g.

산출

#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 월드 공간에서 그리드의 한 변의 길이입니다.
  • c 그리드의 각 가장자리를 따라 정점의 수입니다.
  • 그리드를 생성하는 함수 는 꼭짓점의 월드 공간 좌표 xz(+ y 증가) 의 두 가지 입력을 가져와 정점의 월드 공간 위치를 반환 하는 함수로 호출됩니다 .
  • w pgm의 너비입니다
  • h pgm의 높이입니다
  • m뷰 / 투영 매트릭스입니다. 만드는 데 사용되는 인수 m는 ...
    • 라디안의 시야
    • pgm의 종횡비
    • 클립 평면 근처
    • 먼 클립 비행기
    • 카메라 위치
    • 카메라 대상
    • 벡터를

렌더러는 더 많은 기능, 더 나은 성능 및 더 나은 골프를 쉽게 누릴 수 있었지만 재미있었습니다.


2
와우, 그것은 믿어지지 않는다!
MD XF

1
전혀 그렇지 않습니다 ... 가십시오!
Patrick Purcell

1
133 바이트를 줄였습니다!
MD XF

1
이것은 대단하다! 당신이 그 모든 것을 어디서 배웠는지 말해 줄 수 있다면, 그것은 좋을 것입니다 !
HatsuPointerKun

1
@HatsuPointerKun 즐겁습니다! 이 튜토리얼 ... opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices ...는 시작하기 좋은 곳입니다.
Patrick Purcell

9

수학, 47 바이트

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

입력 σ로 사용

입력

[2]

산출
여기에 이미지 설명을 입력하십시오

LLlAMnYP 덕분에 -2 바이트


1
매스 매 티카 우승? P
MD XF

3
2 바이트를 저장E^(-(x^2+y^2)/2/#^2)
LLlAMnYP

6

R, 105 (102) 87 86 바이트

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

STDIN에서 Sigma를 가져옵니다. 행 벡터 생성 -6하는 6단계에 .1모두를 x하고 y, 이어서 생성 121x121의 외적을 고려하여 매트릭스 xy. 이것은 matrix치수를 호출 하고 지정하는 것보다 짧습니다 . 이제 행렬이 채워져 있지만 덮어 쓰기 때문에 괜찮습니다.

for있는 숫자 위에 -loop 루프 x에서 벡터화 동작을 활용 R한번에 밀도 행렬의 하나의 행을 생성.

(s)apply다시 벡터화 된 연산을위한 더 짧은 방법입니다. 영웅과 마찬가지로 행렬 생성을 자체적으로 처리하여 몇 바이트를 절약합니다.

여기에 이미지 설명을 입력하십시오

128 125 110 109 바이트이지만 방법 더 화려한 :

이 플롯은 plotly패키지에 의해 생성됩니다 . 안타깝게도 사양은 약간 까다롭기 때문에 많은 바이트가 필요합니다. 그래도 결과는 정말 환상적입니다. 직접 시도해 보는 것이 좋습니다.

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")

쏴


나는 질문에 그래프에 줄 번호가 필요 하지 않다고 명시했다 . 두 번째 제출은 괜찮다.
MD XF

아, 나는 그것을 놓쳤다. 솔루션을 교체했습니다. 나는 plotly줄거리가 여전히 여기에 포함되어 있음을 보증하기에 충분 하다고 생각합니다 .
JAD

두 가지 방법 모두 많이 있습니다보다 훨씬 더 장식 : P
MD XF

s한 번만 사용하므로 시작할 때 2*scan()^2제거하고 제거 할 수 s=scan();있습니까? 3 바이트를 절약 할 수 있습니다.
KSmarts

6

애플 소프트 베이직, 930 783 782 727 719 702 695 637 바이트

-72 바이트로 작동하는 프로그램 덕분에 ceilingcat 내 오류를 안보 및 단축 알고리즘

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

Ungolfed 버전은 여기입니다.

입력이 주어지면 1:

입력 -1

입력이 주어지면 2:

입력 -2


1
이것은 다시 BASIC의 우월성을 보여줍니다 ....

몇 가지 더를 저장할 수있는 것은 교체 제안, 등 또한 (10)와 같은 일부 자주 사용되는 값에 1 개 이상의 변수를 설정하여 바이트 EXP(X)/(2*3.14159*S1*S1)와 함께EXP(X)*M
ceilingcat
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.