Loading [MathJax]/jax/element/mml/optable/BasicLatin.js

이전 포스팅(https://kipl.tistory.com/731)에서 단위구에서 두 점 사이거리의 평균을 구하는 과정에서 사이거리에 대한 확률밀도함수를 소개하였고, 또 단위원에서 사이거리에 대한 확률밀도함수를 구체적으로 구했다. 이제 단위원에서의 기법을 이용해서 단위구에서 사이거리 분포에 대한 확률밀도함수를 구하자. 두 점의 사이거리 s의 확률밀도함수는

P(s)=1B31unit balld3rd3rδ(|rr|s), B1=4π3

로 쓰인다. 주어진 단위구 내부의 한 지점 r에 대해서 적분은 S(r,s)=unit balld3rδ(|rr|s)

r에서 반지름 s인 구면이 단위구에 포함된 면적을 나타낸다. 그리고 이 값은 r의 방향에 무관하게 단위구 중심에서 거리에만 의존함을 쉽게 알 수 있다, 즉 

S(r,s)=S(r,s)

이다. 따라서 r+s가 1보다 작을 때와 클 때 두 경우를 별도로 고려해야 한다. 작은 경우는 반지름 s인 구면이 완전히 단위구 내부에 포함되므로 

r+s<1      S(r,s)=4πs2

이고, 큰 경우는 (단위원의 경우 그림을 참조하면: https://kipl.tistory.com/732) 4πs2에서 단위구 밖으로 나가는 구면캡(spherical cap)의 면적을 제외하면 된다. 구면캡의 경도각 범위가 cosθ=1r2s22rs이므로 구면캡의 입체각은 

ΔΩ=2πθ0sinθdθ=2π(11r2s22rs)=2π(r+s)212rs

   r+s>1       S(r,s)=(4πΔΩ)s2=4πs21(rs)24rs

따라서 사이거리에 대한 확률밀도함수는

P(s)=1B214π10r2drS(r,s)

=1B214π1s0r2dr(4πs2)+1B214π11sr2dr(4πs21(rs)24rs)

=316s2(2s)2(4+s)

거리의 평균:

<s>=

거리제곱의 평균:

<s2>=02P(s)s2=65

거리역수의 평균:

<1s>=02P(s)1sds=65

728x90
,

단위원에서 선택한 임의의 두 지점의 사이거리 s0s2이 확률밀도함수는 

P(s)=1D12unit diskd2rd2rδ(|rr|s),    D1=π

먼저

L(r,s)=unit diskd2rδ(|rr|s)

은 델타함수 제한조건 때문에 r을 중심으로 한 반지름 s인 원과 단위원의 겹치는 영역의 경계의 길이를 의미함을 알 수 있다. 이 L(r,s)가 구해지면 P(s)는 이 값을 단위원에 대해 적분을 하면 되는데, 그 값은 단위원의 중심엣 r가 거리에만 의존함을 쉽게 알 수 있다. 따라서 r가, 예를 들면  x축 위에 있는 경우만 고려하면 충분하다. 또, L(r,s)=L(|r|=r,s)이므로

unit diskd2rL(r,s)=2π01rdrL(r,s)

이제 x을 중심으로 한 반지름 s인 원이 완전히 단위원에 포함이 되는 경우는 원과 단위원의 겹치는 영역이 반지름 s인 원이므로 

r+s<1     L(r,s)=2πs

이고, 원호 일부가 단위원 밖으로 나가는 경우는 두 가지 경우(그림의 θ가 예각 또는 둔각)를 생각할 수 있는데,


두 경우 모두 단위원과 겹치는 영역의 원호의 길이는 그림에서 2(πθ)s인데, sinφ=ssinθ,    cosφscosθ=r

   cosθ=1r2s22rs

r+s>1    L(r,s)=2(πθ)s=2s(πcos11r2s22rs)

로 표현된다. 따라서 사이거리에 대한 확률밀돟함수는

P(s)=2ππ201rdrL(r,s)=4s01srdr+4sπ1s1rdr(πcos11r2s22rs)

=4sπcos1s22s2π1s24

이 분포를 이용하면 단위원 내부에서 선택된 두 점간의 평균거리는

|rr|=02P(s)sds=12845π=0.9054

|rr|2=02P(s)s2ds=1

1|rr|=02P(s)1sds=163π

728x90
,

단위구 내의 두 지점을 r1, r2라면 두 지점이 선택될 확률이 

P(r1,r2)=dr13B1×dr23B1,    B1=volume of unit ball=4π3이므로 두 지점의 사이거리의 평균은

|r1r2|=1B12unit ball|r1r2|dr13dr23

r1r2의 사이각이 θ일 때 고정된 r1에 대해서 r2의 극좌표 고도각으로 선택하면 r2에 대한 적분은

I2=unit ball|r1r2|dr23

=2π01r22dr211dcosθr12+r222r1r2cosθ

=2π301r22dr2(r1+r2)3|r1r2|3r1r2

=π(1+23r12r1415)

따라서 사이거리의 평균은

|r1r2|=4πB1201r12dr1π(1+23r12r1415)

=1B1264π235=3635

이전 포스팅에서 거리 역수의 평균이 65임을 보였는데, 평균거리가 이 값의 역수로 주어지지는 않는 점이 의외다.

아래 그림은 거리에 대한 확률밀도함수를 Monte Carlo 시뮬레이션으로 구한 결과이다. 실제로 거리에 따른 확률밀도함수를 임의의 차원에서 구할 수 있는데, 3차원의 단위구는(ref: J. Math. Phys., Vol. 41, No. 4, April 2000, https://kipl.tistory.com/733)

P3(s)=316s2(2s)2(4+s),    0s2

로 계산이 된다. 이 확률밀도함수의 최대값은 s=1이 아니라 s=151051=1.04939 에서 나온다. P3(s)를 이용하면<s>=02P3(s)sds=3635를 얻고, 거리의 역수의 평균은<1s>=02P3(s)1sds=65도 얻을 수 있다. 

#define TWO_PI 6.28318530717958647692
// picking a random vector inside an unit ball;
void randomVector(double &x, double &y, double &z) {
    double a = double(rand()) / RAND_MAX;		//[0,1] = radius;
    double b = double(rand()) / RAND_MAX * 2 - 1; //[-1,1] = cos(theta);
    double c = double(rand()) / RAND_MAX * TWO_PI; //[0, 2PI] = azimuthal; 
    a = pow(a, 1.0 / 3.0);
    x = a * sqrt(1 - b * b) * cos(c);
    y = a * sqrt(1 - b * b) * sin(c);
    z = a * b;
}
// Calculate the distance between two randowm points selected 
// inside an unit ball;
double randomDistance() {
    double x1, y1, z1, x2, y2, z2;
    randomVector(x1, y1, z1);
    randomVector(x2, y2, z2);
    x1 -= x2;
    y1 -= y2;
    z1 -= z2;
    return sqrt(x1 * x1 + y1 * y1 + z1 * z1);
}
void meanDistSphere(CRaster& raster) {
    double R = 100;
    int trials = 5000000;
    srand(unsigned(time(NULL)));
    std::vector<int> hist(2 * int(R + .5) + 1, 0);
    for (int i = trials; i-->0;) {
        double d = R * randomDistance();
        hist[int(d)]++;
    }
    double s = 0, sx = 0, sxx = 0;
    double maxh = 0;
    for (int i = hist.size(); i--> 0; ) {
        double h = hist[i];
        maxh = max(h, maxh);
        s += h;
        sx += h * i;
        sxx += h * i * i;
    }
    double mean = sx / s;
    double var = (sxx - sx / s) / s;
    double sdev = sqrt(var);
    // CRaster raster;
    raster.SetDimensions(hist.size(), hist.size(), 24);
    CSize sz = raster.GetSize();
    memset(raster.GetDataPtr(), 0xFF, raster.GetDataSize());
    for (int x = sz.cx; x--> 0; ) {
        int h = int(double(sz.cy) * hist[x] / maxh);
        for (int y = h; y--> 0; ) 
            raster.SetPixel(x, sz.cy-1-y, 0);
    }
    // SaveRaster(raster, "hist.bmp");
}
728x90
,