Processing math: 13%

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

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

|r1r2|=1B21

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
,