Накресліть розподіл Гаусса у 3D


10

У теорії ймовірностей звичайний (або гауссовський) розподіл - це дуже поширений безперервний розподіл ймовірностей. Звичайні розподіли важливі в статистиці і часто використовуються в природничих і соціальних науках для представлення реально оцінених випадкових величин, розподіл яких не відомий.

Змагання

Ваше завдання полягає в тому, щоб побудувати щільність ймовірності розподілу Гаусса на тривимірній площині . Ця функція визначається як:

Де:




A = 1, σ x = σ y = σ

Правила

  • Ваша програма повинна приймати один вхід σ , стандартне відхилення.
  • Ваша програма повинна надрукувати 3D-графік розподілу Гаусса найвищою якістю, як це дозволяє ваша мова / система.
  • Ваша програма може не використовувати прямого гауссового розподілу чи побудованої щільності ймовірностей.
  • Ваша програма не повинна припинятися.
  • Ваш сюжет може бути чорно-білим або кольоровим.
  • На вашій ділянці внизу повинні бути сітки. Лінії сітки з боків (як показано в прикладах) непотрібні.
  • На вашій ділянці не потрібно мати рядків поряд із лініями сітки.

Оцінка балів

Як завжди в , виграш подання з найменшими байтами! Я ніколи не можу "прийняти" відповідь за допомогою кнопки, якщо тільки вона не є надзвичайно маленькою та інтуїтивно зрозумілою.

Приклад виведення

Ваш результат може виглядати приблизно так:

5

Або це могло виглядати так:

6

Більше дійсних результатів . Недійсні виходи .


Мене збентежило те, що ти щойно показав функцію для осі X. Чи потрібно брати окремі входи / виходи для сигми X та Y та mu?
Скотт Мілнер

Тож чи слід вважати, що μ дорівнює 0? А яку шкалу вам потрібно для х і у? Якщо діапазони x-і y вибираються дуже малі відносно σ, графік, по суті, буде схожий на постійну функцію.
Грег Мартін

(Щодо двовимірного розподілу, я вважаю, що зрозуміліше, якщо ви використовуєте | x-μ | ^ 2 у визначенні, а не (x-μ) ^ 2.)
Грег Мартін,

@GregMartin Відредаговано.
MD XF

2
Ще не зрозуміло ... що таке x_o і y_o і θ?
Грег Мартін

Відповіді:


7

Gnuplot 4, 64 62 61 60 47 байт

(Зв'язано з Mathematica ! WooHoo!)

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 4, оскільки в Gnuplot 5 $nпосилання на аргументи застаріли і замінені на жаль більш багатослівними ARGn.

Вибірка з σ = 3:

Вибірка зразка

Цей вихід є нормальним згідно з ОП .


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 По-перше, я не впевнений, чи прозорість графіка добре. Я, чесно кажучи, не дуже люблю це, тому я не був впевнений, чи буде це нормально тут. По-друге, графік за замовчуванням починається на одну одиницю висотою, і я не впевнений, чи з цим все гаразд. По-третє, оскільки графік починається на одну одиницю високої, я не впевнений, що непропорційність графіка порівняно з графіками, наведеними в оригінальній публікації, все в порядку. Однак якщо з вами це все гаразд, я із задоволенням зробить це основною відповіддю.
Р. Кап

@MDXF Насправді я збирався опублікувати його як оригінальну відповідь, але з цих причин я вирішив не робити, а замість цього розмістив поточну відповідь.
Р. Кап

@MDXF Насправді я можу зробити його ще коротшим, якщо це нормально. Я розумію, якщо цього не буде, але запитати не завадить. Це за замовчуванням Gnuplot, побудував би щільність ймовірності розподілу Гаусса з Sigma 2без будь-яких змін середовища.
Р. Кап

@MDXF Напевно, я міг би запитати, перш ніж публікувати свою оригінальну відповідь, але в той час я дуже хотів розмістити відповідь.
Р. Кап

14

C ++, 3477 3344 байт

Кількість байтів не включає зайвих нових рядків.
MD XF відіграв 133 байти.

C ++ не може змагатися за це, але я думав, що було б цікаво написати програмний рендер для виклику. Я вирвав і пограв декілька фрагментів GLM для 3D-математики і використав лінійний алгоритм 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 - кількість вершин уздовж кожного краю сітки.
  • Функція, яка створює сітку, називається функцією, яка займає два входи, координати світового простору вершини xі z(+ y йде вгору) і повертає положення світової простору вершини.
  • w - ширина pgm
  • h - висота пгм
  • mє матрицею перегляду / проекції. Аргументи, які використовуються для створення m, ...
    • поле зору в радіанах
    • співвідношення сторін pgm
    • біля площини кліпу
    • дальній площині кліпу
    • положення камери
    • ціль камери
    • вгору вектор

Здійснювач може легко мати більше можливостей, кращі показники та краще гольфувати, але я розважався!


2
Ого, це неймовірно!
MD XF

1
Зовсім не ... піди на це!
Патрік Перселл

1
Ось ви йдете, 133 байти!
MD XF

1
Це приголомшливо! Якби ви могли сказати мені, де ви все це дізналися, це було б чудово !
HatsuPointerKun

1
@HatsuPointerKun Радий, що вам сподобається! Цей підручник ... opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices - чудове місце для початку.
Патрік Перселл

9

Математика, 47 байт

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

приймає за вхід σ

Вхідні дані

[2]

вихід
введіть тут опис зображення

-2 байти завдяки LLlAMnYP


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. Створює вектор від -6до 6з кроком .1для обох xі y, потім створює 121x121матрицю, взявши зовнішнє твір xі y. Це коротше, ніж виклик 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

Applesoft BASIC, 930 783 782 727 719 702 695 637 байт

-72 байти та робоча програма, завдяки тому, що стетовий кот помітив мою помилку та скорочений алгоритм

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

Тут неперевершена версія.

При введенні 1:

вхід-1

При введенні 2:

вхід-2


1
Це ще раз показує перевагу BASIC ....

Можна зберегти ще декілька байтів, встановивши одну чи кілька змінних на якесь часто використовуване значення, наприклад 10. Також пропонуємо замінити EXP(X)/(2*3.14159*S1*S1)наEXP(X)*M
roofcat
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.