열방정식에서 매질에서 열의 확산은 특별히 선호된 방향이 없이 모든 방향에 대해서 동등하다. 물론 매질의 열전도도가 다르면 국속적으로 열확산이 균일하지 않을 수는 있어도 방향을 따지는 않는다. 그러면 방향에 따라 열의 확산을 정도를 다르게 설정하려면 어떻게 해야 할까? 이는 열방정식을 이용해서 이미지의 smoothing을 하는 필터에서도 동일한 상황이 생길 수 있다. 특히 에지를 보존하면서 smoothing을 할 때 에지에 수직방향으로는 확산이 잘 안일어나게 억제해야 할 필요가 있다. 이를 위해 2차원 열방정식의 우변을 살펴보자. 우변은 온도 $u(x,y;t)$의 Laplacian이 들어오는데 보다 일반적인 Hessian matrix $H$을 써서 표현하면 그 의미가 더 명확해진다.

$$ H = \begin{pmatrix} u_{xx} & u_{xy}\\ u_{xy} & u_{yy} \end{pmatrix}$$

$$ u_{xx} + u_{yy} = (1, 0).H. \begin{pmatrix} 1 \\0\end{pmatrix}+ (0,1) . H. \left( \begin{matrix} 0 \\1 \end{matrix} \right) = \text{Tr}\left ((e_1 \otimes  e_1^T + e_2 e \otimes _2^T).H\right)$$

즉, Laplacian은 평면에서 두 단위 벡터  $e_1=(1,0)^T$과 $e_2 =(0,1)^T$ 각각에 Hessian을 작용한 결과를 다시 자신과 내적을 한 값을 동일하게 더하여 나온다. 따라서 $x$방향이나 $y$방향에 무관하게 등방적으로 작용하게 된다. 그러나 $x$방향과 $y$방향에 다른 가중치 $\alpha, \beta\ne \alpha$를 둔다면 등방성은 사라지게 될 것이고 가중치가 큰 방향으로 열의 확산이 더 잘 일어나게 된다.

$$ \alpha u_{xx} + \beta u_{yy}= \alpha \times (1, 0).H. \left(\begin{matrix} 1 \\0\end{matrix} \right)+ \beta(0,1) . H. \left( \begin{matrix} 0 \\1 \end{matrix} \right) = \text{Tr}\left((\alpha e_1 \otimes e_1^T + \beta e_2 \otimes e_2^T).H \right)$$  

일반적으로 $x,y$ 방향의 단위벡터 대신에 서로 직각이 단위벡터를 사용해서 비등방성을 줄 수 있다. 예를 들면 에지 방향에 수직한 방향으로 확산을 억제하고 싶은 경우에는 그래디언트의 공변행렬 $\left(\begin{matrix} u_x^2 & u_x u_y\\ u_x u_y& u_y^2 \end{matrix}\right)$의 두 고유벡터 $v_1$, $v_2$를 이용할 수 있다. 이 경우 고유값이 큰 쪽에 해당하는 고유벡터의 방향이 에지에 수직방향이고, 작은 쪽이 에지 방향을 가리킨다. 

$$    \text{Tr}\left( (c_1 v_1 \otimes v_1^T + c_2 v_2 \otimes v_2^T ).H\right) = \text{Tr}(T.H) \\T= c_1 v_1 \otimes v_1^T + c_2 v_2 \otimes v_2^T $$

이 경우 비등방적 확산은 텐서필드 $T$에 의해서 제어가 되고 열(확산)방정식은 다음과 같이 간단한 형식으로 표현할 수 있다.

$$ u_t = \text{Tr} (T.H)$$

텐서필드는 고유벡터의 텐서곱을 선형결합해서 만드는데 계수 $c_1$과 $c_2$를 어떻게 선택하는가에 따라 확산의 유형이 달라진다. 에지를 보존하도록 컨트롤하기 위해서는 고유값이 큰 방향으로 가중치가 작게 되도록 선택을 해야 한다. 많이 사용되는 예로는 고유값이 각각 $\lambda_1 < \lambda_2$일 때

$$ c_ 1 = (1 + (\lambda_1 + \lambda_2)/s)^{-p_1},  ~~c_2 = (1+ (\lambda_1 + \lambda_2)/s)^{-p_2}, ~~0<p_1 < p_2$$ 

로 잡는다.

 
 
 
 
 
 
 
 
 
 

void AnisoDiffusion(double **image, int width, int height) {
    // preparation;
    // ....

    // main iteration loop
    for (int iter = 0; iter < max_iter; iter++) {
        // compute gradients;
        Gradient(image, width, height, Gx, Gy);
        // compute the tensor field T, used to drive the diffusion
        for (int x = width; x-- > 0;) {
            for (int y = height; y-- > 0;) {			
                // covariance matrix;
                double a = Gx[x][y] * Gx[x][y]; 
                double b = Gx[x][y] * Gy[x][y];
                double d = Gy[x][y] * Gy[x][y];
                // eigenvalues of symm matrix [a,b;b,d]
                double lambda1, lambda2;
                Eigenvalues(a, b, d, lambda1, lambda2); // 0 <= lambda1 <= lambda2;
                // eigenvector for lambda1; ev1=(u,v);
                double u, v;
                Eigenvector(a, b, d, lambda1, u, v);
                // eigenvector for lambda2: ev2=(-v,u);

                double val1 = lambda1 / drange2; 
                double val2 = lambda2 / drange2;
                double f1 = pow(1 + val1 + val2, -a1);
                double f2 = pow(1 + val1 + val2, -a2);
                // T = f1 * (ev1.ev1^T) + f2* (ev2.ev2^T)
                T[0][x][y] = f1 * u * u + f2 * v * v; //(0,0)
                T[1][x][y] = (f1 - f2) * u * v;       //(0,1)=(1,0)
                T[2][x][y] = f1 * v * v + f2 * u * u; //(1,1)
            }
        }
        double xdt = 0.0;
            
        // compute the velocity and update the iterated image
        for (int x = width; x-- > 0;) {
            int px = max(x - 1, 0);
            int nx = min(x + 1, width - 1);
            for (int y = height; y-- > 0;) {
                int py = max(y - 1, 0);
                int ny = min(y + 1, height);
                double Ipp = image[px][py]; 
                double Ipc = image[px][y] ; 
                double Ipn = image[px][ny]; 
                double Icp = image[x] [py]; 
                double Icc = image[x] [y] ; 
                double Icn = image[x] [ny]; 
                double Inp = image[nx][py]; 
                double Inc = image[nx][y] ;
                double Inn = image[nx][ny];
                // Hessian matrix of image; H=[Ixx,Ixy;Ixy,Iyy]
                double Hxx = Inc + Ipc - 2 * Icc;
                double Hyy = Icn + Icp - 2 * Icc;
                double Hxy = (Ipp + Inn - Ipn - Inp) / 4;
                // veloc = trace(T.H)
                veloc[x][y] = T[0][x][y] * Hxx + 2 * T[1][x][y] * Hxy + T[2][x][y] * Hyy;
            }
        }

        // find xdt coefficient
        if (dt > 0) {
            double max1 = veloc[0][0], min1 = veloc[0][0];
            for (int x = width; x-- > 0;) {
                for (int y = height; y-- > 0;) {
                    if (veloc[x][y] > max1) max1 = veloc[x][y];
                    if (veloc[x][y] < min1) min1 = veloc[x][y];
                }
            }
            xdt = dt / max(fabs(max1), fabs(min1)) * drange0;
        } else xdt = -dt;

        // update image
        for (int x = width; x-- > 0;) {
            for (int y = height; y-- > 0;) {
                image[x][y] += veloc[x][y] * xdt;
                // normalize image to the original range
                if (image[x][y] < initial_min) image[x][y] = initial_min;
                if (image[x][y] > initial_max) image[x][y] = initial_max;
            }
        }
    }
    // clean memories;
};
 
 
 
 
 
 
 
 
 
728x90

'Image Recognition' 카테고리의 다른 글

Edge Preserving Smoothing  (0) 2024.02.14
Watershed Segmentation  (0) 2021.02.27
Local Ridge Orientation  (0) 2021.02.21
Contrast Limited Adaptive Histogram Equalization (CLAHE)  (3) 2021.02.15
Fixed-Point Bicubic Interpolation  (1) 2021.01.19
Posted by helloktk
,

영상처리에서 $2\times2$ 행렬의 고유값과 고유벡터를 수치적으로 구해야 하는 상황이 많이 생긴다. 이 경우 2차인 특성방정식을 풀어서 고유값을 구하게 되는데, 두 고유값의 차이가 매우 큰 경우 단순한 근의 공식을 적용한 결과는 수치적으로 부정확한 값을 줄 수 있다. 이를 피하는 방법을 간단히 살펴보자.

 

이차방정식 

$$x^2 - b x +c =0$$

의 두 해는 

\begin{align}x_1 = \frac{b + d}{2},\quad x_2 = \frac{b - d}{2},\qquad d= \sqrt{b^2 - 4c}\end{align}

로 표현된다.  고유값의 특성방정식으로 보면 계수 $b$는 두 고유값의 합, 판별식 $d$는 두 고유값의 차이다. 그런데 $b ^2 \gg c $ 판별식 $d$는 $b$와 매우 근접한 수치이므로 거의 비슷한 두 수의 뺄셈으로 표현된 $x_2$의 수치계산 결과는 매우 부정확해질 수 있다. 예로 

$$ x^2 - 10^8 x +1=0$$

의 해를 프로그램으로 구하면 

	double b = 1.0e8, c = 1.;
	double d = sqrt(b * b - 4. * c);
	double x1 = (b + d)/2., x2 = (b - d)/2.;
	TRACE("x1=%e, x2=%e", x1, x2);

프로그램을 돌리면 얻게 되는 결과는

$$ \tt  x1=1.000000e+008, \qquad x2=7.450581e-009$$

그런데 테일러 전개를 사용하면 $x_2$는 

$$x_2 = \frac{b}{2}\left( 1 - \sqrt{1-\frac{4c}{b^2}} \right)  \approx \frac{b}{2}\times \frac{2c}{b^2} = \frac{c}{b}=10^{-8}$$ 

이어야 한다. 따라서 $x_2$를 바로 근의 공식으로 구할 경우 25%정도의 오차가 생긴다. 이런 경우에는 근의 공식에 의한 직접적인 계산보다는 이차방정식의 특성을 이용하는 것이 수치적으로 더 정교한 답을 얻을 수 있다. 두 근의 곱이 $x_1 x_2 =c$이므로 $x_2$는 

$$x_2 = c / x_1\approx 10^{-8}$$

을 통해서 구하는 것이 더 수치적으로 정교하다.  일반적으로 두 근의 합  $b$가 양수인 경우는  $x_2$를, 음수인 경우는 $x_1$을 두 근의 곱을 이용해서 계산하는 것이 더 정교한 수치값을 얻을 수 있다.

// Find two roots of a quadratic eq: x * x - b * x + c = 0;
void Quadratic2(double b, double c, double& x1, double& x2) {
    double d = sqrt(b * b - 4. * c);
    x1 = (b + d)/ 2., x2 = (b - d)/ 2.;
    TRACE("x1=%e, x2=%e\r\n", x1, x2);
    if (b > 0) {
        if (x1 != 0) x2 = c / x1;
        TRACE("Improved: x1=%e, x2=%e\r\n", x1, x2);
    } else {
        if (x2 != 0) x1 = c / x2;
        TRACE("Improved: x1=%e, x2=%e\r\n", x1, x2);
    }
}

이 경우 결과는 훨씬 더 정교한 값을 보여준다.

$$\tt Improved: x1=1.000000e+008, \quad x2=1.000000e-008$$

 
 
 
 
 
 
 
 
 
 
 
 
 
 
728x90

'Mathematics' 카테고리의 다른 글

Fourier Interpolation  (0) 2024.03.20
Generalized eigenvalues problem  (0) 2024.03.02
열방정식의 Green function  (0) 2024.02.12
지구의 나이는?  (0) 2024.02.11
n 차원 공의 부피  (2) 2024.02.07
Posted by helloktk
,

\begin{gather}BF[I]_{\bf p} = \frac{1}{W_\bf{p}}  \sum_{ {\bf q} \in S} G_{\sigma_s} (||{\bf p} - {\bf q}||) G_{\sigma_r}(|I_{\bf p} - I_{\bf q} |) I_{\bf q} \\  W_{\bf p} = \sum_{{\bf q}\in S} G_{\sigma_s} (||{\bf p}-{\bf q}||) G_{\sigma_r}(|I_{\bf p} - I_{\bf q} |) \\ G_\sigma ({\bf r}) = e^{ - ||\bf{r}||^2/2\sigma^2 }\end{gather}

 

Bilateral Filter
Gaussian Filter

 

smoothing based on the nonlinear heat eq

// sigmar controls the intensity range that is smoothed out. 
// Higher values will lead to larger regions being smoothed out. 
// The sigmar value should be selected with the dynamic range of the image pixel values in mind.
// sigmas controls smoothing factor. Higher values will lead to more smoothing.
// convolution through using lookup tables.
int BilateralFilter(BYTE *image, int width, int height, 
    double sigmas, double sigmar, int ksize, BYTE* out) {
    //const double sigmas = 1.7;
    //const double sigmar = 50.;
    double sigmas_sq = sigmas * sigmas;
    double sigmar_sq = sigmar * sigmar;
    //const int ksize = 7;
    const int hksz = ksize / 2;
    ksize = hksz * 2 + 1;
    std::vector<double> smooth(width * height, 0);
    // LUT for spatial gaussian;
    std::vector<double> spaceKer(ksize * ksize, 0);
    for (int j = -hksz, pos = 0; j <= hksz; j++) 
        for (int i = -hksz; i <= hksz; i++) 
            spaceKer[pos++] = exp(- 0.5 * double(i * i + j * j)/ sigmas_sq); 
    // LUT for image similarity gaussian;
    double pixelKer[256];
    for (int i = 0; i < 256; i++)
        pixelKer[i] = exp(- 0.5 * double(i * i) / sigmar_sq);

    for (int y = 0, imgpos = 0; y < height; y++) {
        int top = y - hksz;
        int bot = y + hksz;
        for (int x = 0; x < width; x++) {
            int left = x - hksz;
            int right = x + hksz;
            // convolution;
            double wsum = 0;
            double fsum = 0; 	
            int refVal = image[imgpos];
            for (int yy = top, kpos = 0; yy <= bot; yy++) {
                for (int xx = left; xx <= right; xx++) {
                    // check whether the kernel rect is inside the image;
                    if ((yy >= 0) && (yy < height) && (xx >= 0) && (xx < width)) {
                        int curVal = image[yy * width + xx];
                        int idiff = curVal - refVal;
                        double weight = spaceKer[kpos] * pixelKer[abs(idiff)];
                        wsum += weight;
                        fsum += weight * curVal;
                    }
                    kpos++;
                }
            }
            smooth[imgpos++] = fsum / wsum;
        }
    }

    for (int k = smooth.size(); k-- > 0;) {
        int a = int(smooth[k]);
        out[k] = a < 0 ? 0: a > 255 ? 255: a;
    }
    return 1;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728x90

'Image Recognition > Fundamental' 카테고리의 다른 글

Cubic Spline Kernel  (1) 2024.03.12
Ellipse Fitting  (0) 2024.03.02
영상에서 Impulse Noise 넣기  (2) 2023.02.09
Canny Edge: Non-maximal suppression  (0) 2023.01.11
Statistical Region Merging  (0) 2022.06.11
Posted by helloktk
,

열방정식은 매질에서 열이 전달되는 과정을 기술한다. 열은 온도차이가 있을 때 전달되는 에너지로 온도 분포 $u(\vec{r},t)$가 주어진 경우 주변으로 나가는 열에너지는 온도의 gradient $\nabla u$에 비례한다. 

$$ \text{heat flux: }\quad  \vec{j}= \kappa (u)\nabla u$$

$\kappa$는 매질에서 열이 얼마나 잘 전도는지를 표현하는 일반적으로 $u$에 의존할 수 있다. 균일하고 등방적인 매질인 경우는 $\kappa$가 일정한 상수에 해당한다. 국소적으로 단위부피당 단위시간당 빠져나가는 열에너지는 thermal flux의 divergence에 비례하고 이 값이 0이 아니면 그 지점의 온도 변화를 만든다. 따라서 온도는 다음과 같은 방정식을 만족한다.

$$ u_t = \nabla \cdot \vec{j}  = \nabla\cdot(\kappa \nabla u)$$

이 방정식은 물질의 확산 현상에도 적용이 가능한데 이 경우 $u$는 물질의 밀도분포에 해당할 것이다.

$\kappa$가 상수인 경우 이 방정식은 선형방정식으로 초기 온도분포 $u(x,t=0)=f(x)$가 주어지면 해는 사이즈가 $\sigma = \sqrt{2\kappa t}$인 가우시안 커널(heat kernel 또는 Greeen function)과 초기 온도분포의 convolution으로 표현할 수 있다. 1차원 선형 열방정식의 해는 구체적으로 다음과 같이 표현된다.

\begin{align} u(x,t) =  \int \frac{1}{\sqrt{4\pi \kappa t}} e^{- (x-y)^2 / 4\kappa t } f(y) dy = ( G_{\sigma} * f)(x,t)\\G_\sigma (x) = \frac{1}{\sqrt{2\pi\sigma} }  e^{- x^2/2\sigma^2} \end{align}

열방정식은 뜨거운 커피가 담긴 잔을 방에 놓았을 때 방 안의 온도가 어떻게 변할지도 알 수 있게 해 준다. 물론 경험적으로 커피의 온도는 내려가고 방안은 잔의 주변부터 점차로 데워져서 나중에서는 모든 부분이 일정한 온도를 가지는 평형상태에 도달한다. 이는  가우시안 커널의 크기가 $\sqrt{t}$에 비례하므로 시간이 흐를수록 모든 지점에서 온도는 일정한 값으로 수렴할 것임을 쉽게 예측할 수 있다.

이 열방정식을 이미지에 대해서도 적용할 수 있다. 이 경우 초기 온도분포는 주어진 이미지의 명암값에 해당한다. 열방정식의 우변을 이미지에 적용하면 Gaussian 블러링에 해당하고, 시간은 블러링의 순차적인 적용 횟수를 의미한다. 이미지가 블러링 되는 경우 영상이 담고 있는 정보는 점점 잃게 되는데 이를 방지하기 위해서는 영상의 에지 정보를 보존하는 방법으로 열방정식을 변형시켜 보자. 영상에서 에지영역에서는 gradient 값이 커지므로 이 지점에서는 커널사이즈를 작게 (열방정식 관점에서는 열전도도를 줄임) 만들면 블러링 효과가 줄어들게 된다. 이를 위해서 다음과 같은 열전도도 함수를 도입하자.

$$ \kappa (u) = \frac {1}{1+ |\nabla u|^2/\lambda^2 }$$

여기서 $\lambda$은 contrast 파라미터로 에지의 세기가 $|\nabla| \gg \lambda$ 영역에서는 블러링의 영향을 거의 받지 않게 되어 열방정식을 적용하더라도 에지에 대한 정보 손실은 거의 일어나지 않는다. 그러나 $\kappa $가 상수가 아닌 경우는 열방정식은 비선형이므로 해를 명시적으로 쓸 수 없고 오직 수치해석적으로만 구할 수 있다.

먼저 미분연산자(Sobel operator: $\lambda$의 설정은 미분연산자의 normalization을 고려해야 함)을 이용해서 이미지의 gradient을 구하면 flux $\vec{j}$을 구할 수 있고, 다시 $j_x$에 대해서 $x-$방향 미분, $j_y$에 대해서 $y-$방향 미분을 해서 $\vec{j}$의 divergence, 즉 이미지의 일반화된 Laplace 연산 결과를 얻을 수 있다. 이 결과에 시간간격을 곱한 양을 이전 이미지에 더하여 새로운 이미지를 얻는다. 이 과정을 반복적으로 수행하면 된다.

$$ u(x,y, t+\Delta t) = u(x, y, t) + \Delta t \times \nabla \cdot (\kappa (|\nabla u| ) \vec{j})$$

$\kappa$가 상수일 때 $t \to \kappa t$로 시간변수를 바꾸면 열방정식은 차원이 없는 형태로 되고, $\kappa <1$이므로 시간간격은 $\Delta t \ll 1$를 만족하도록 선택해야 한다.

 
 
 

 

$\lambda=50,~\Delta t=0.01$일 때 5 스텝 간격으로의 변화

 
double conductivity(double gmagsq, double lambdasq) {
    return 1.0/ (1.0 + gmagsq/lambdasq);
}
int LaplaceImage(double *img, int w, int h, double lambda, double *laplace) {
    const double lambdasq = lambda * lambda;
    // Sobel gradient 3x3
    const int nn[] = { -w - 1, -w, -w + 1, -1, 0, 1, w - 1, w, w + 1};
    const int sobelX[] = { -1, 0, 1, -2, 0, 2, -1, 0, 1};
    const int sobelY[] = { -1, -2, -1, 0, 0, 0, 1, 2, 1};
    std::vector<double> Gx(w * h, 0);
    std::vector<double> Gy(w * h, 0);
    std::vector<double> Gmag2(w * h, 0);
    const int xmax = w - 1, ymax = h - 1;
    // gradient-x, gradient-y, and mag of gradient.
    for (int y = 1, pos = w; y < ymax; y++) { // pos = w; starting address;
        pos++; //skip x=0;
        for (int x = 1; x < xmax; x++, pos++) {
            double sx = 0, sy = 0;
            for (int k = 0; k < 9; k++) {
                double v = img[pos + nn[k]];
                sx += sobelX[k] * v;
                sy += sobelY[k] * v;
            }
            Gx[pos] = sx;
            Gy[pos] = sy;
            // gx^2 + gy^2;
            Gmag2[pos] = sx * sx + sy * sy;
        }
        pos++; // skip x=xmax;
    }
    // flux;
    for (int y = 1, pos = w; y < ymax; y++) { // pos = w; starting address;
        pos++; //skip x=0;
        for (int x = 1; x < xmax; x++, pos++) {
            double kappa = conductivity(Gmag2[pos], lambdasq);
            // multiply conductivity;
            Gx[pos] *= kappa;
            Gy[pos] *= kappa;
        }
        pos++; // skip x=xmax;
    }
    // divergence -> laplace;
    for (int y = 1, pos = w; y < ymax; y++) { // pos = w; starting address;
        pos++; //skip x=0;
        for (int x = 1; x < xmax; x++, pos++) {
            double sx = 0, sy = 0;
            for (int k = 0; k < 9; k++) {
                sx += sobelX[k] * Gx[pos + nn[k]];
                sy += sobelY[k] * Gy[pos + nn[k]];
            }
            laplace[pos] = sx + sy;
        }
        pos++; // skip x=xmax;
    }
    return 1;
}
void EpSmooth(BYTE *image, int w, int h, BYTE *out) {
    const double lambda = 50.0;
    const double dt = 0.01; //time step;
    const int maxiter = 100;
    std::vector<double> fimage(w * h, 0);
    std::vector<double> laplace(w * h, 0);
    for (int k = fimage.size(); k-- > 0;) fimage[k] = image[k];
    for (int iter = maxiter; iter-- > 0;) {
        LaplaceImage(&fimage[0], w, h, lambda, &laplace[0]);
        // update image;
        for (int k = fimage.size(); k-- > 0; ) 
            fimage[k] += dt * laplace[k];   
    }
    // preparing output;
    for (int k = fimage.size(); k-- > 0; ) {
        int a = int(fimage[k]);
        out[k] = a > 255 ? 255: a < 0 ? 0: a;
    }
}

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728x90

'Image Recognition' 카테고리의 다른 글

Anisotropic Diffusion Filter  (0) 2024.02.23
Watershed Segmentation  (0) 2021.02.27
Local Ridge Orientation  (0) 2021.02.21
Contrast Limited Adaptive Histogram Equalization (CLAHE)  (3) 2021.02.15
Fixed-Point Bicubic Interpolation  (1) 2021.01.19
Posted by helloktk
,

1차원 열방정식은 

$$ u_t (x,t)= \kappa u_{x x}(x,t), \qquad -\infty < x < \infty,~t>0 $$

으로 초기조건이 주어지거나 경계조건이 주어야 한다. $u(x,t)$가 해라면 $u(\lambda  x , \lambda^2 t)$ 또한 해가 됨음 쉽게 확인해 볼 수 있다. 즉, 열방정식은 scale 변경에 불변이 특성을 가진다. 이 특성을 이용해서 열방정식의 특별한 해를 구해보자. scale 불변성을 보면 해의 $x,t$에 대한 의존성은 $x/\sqrt{t}\to \lambda x/\sqrt{\lambda^2 t} = x/\sqrt{t}$의 조합형태로 나타나야 될 것으로 보인다.

$$ u(x,t) = h(x/\sqrt{t})$$

그런데 에너지 보존에 의해서 계의 전체 열에너지는 시간에 무관하게 일정한 값을 가져야 한다. 열에너지가 온도에 비례하므로 총 열에너지는 다음 적분값에 비례한다.

$$ \int_{-\infty}^\infty u(x,t) dx = \text{const}$$

따라서 $u = h(x/\sqrt{t})$와 같은 형태의 해는 에너지 보존을 만족시킬 수 없다.

$$ \int _{-\infty}^\infty h(x/\sqrt{t}) dx = \sqrt{t} \int_{-\infty}^\infty h(y) dy \propto \sqrt{t}$$

그렇지만 $u(x,t) dx $가 스케일 불변꼴이면 가능하므로 

$$u(x,t) = \frac{1}{\sqrt{t}} h( x / \sqrt{t})$$

와 같은 형태로 시도하자. 그러면 열방정식의 좌우변의 항이

$$ u_{xx} = t^{-3/2} h'' (x/\sqrt{t}), \qquad u_t = -\frac{1}{2} t^{-3/2}\Big[ h(x/\sqrt{t}) + h'(x/\sqrt{t}) x/\sqrt{t} \Big] $$

이므로 이를 열방정식에 대입하면 ($y= x/\sqrt{t}$)

\begin{align} \kappa h''(y) + \frac{1}{2} h(y) + \frac{1}{2} y h'(y)=0 \\ \to ~ h''(y) + \frac{1}{2\kappa} (y h(y) )' = 0 \\ \to~ h'(y) + \frac{y}{2\kappa } h(y) = \text{const} \to 0 \end{align}

여기서 $\text{const}=0$ 일 때 해만 고려한다. 이 경우

$$ h(y) = A e^{- y^2/4\kappa} \qquad \to \qquad u(x,t) = \frac{A}{\sqrt{t}} e^{- x^2 / 4\kappa t } $$

인 해를 얻는다. $\int _{-\infty}^\infty u(x,t) dx = 1$로 정규화시키면 적분상수 $A$는

$$ A= \frac{1}{\sqrt{4\pi \kappa } }$$

임을 알 수 있다. 이렇게 정규화된 해를 열방정식의 기본해, Green 함수 또는 heat kernel이라고 부른다.

$$K(x,t) = \frac{1}{\sqrt{4\pi\kappa t} }e^{- x^2/4\kappa t}$$

$K(x,t)$는 $t\to 0^+$일 때 $\delta(x)$와 같은 특성을 가지는데, 물리적으로는 $t=0$ 시점에 원점에 $\delta-$함수로 표현되는 열원을 놓았을 때 열의 확산을 기술하는 해이다. 열방정식이 선형이므로  $x-$축을 따라 분포된 각각의 $\{ \delta(x-x_i)| i=1,2,\dots\}$ 열원의 선형결합도 해가 된다. 

$$ u(x,t) = \sum_i K(x-x_i, t) f_i$$

또한 연속적으로 분포하는 열원의 경우에는 합을 적분형태로 변경하면 되므로 $t=0$일 때 온도분포가 $f(x)$로 주어진 경우 다음 표현이

$$ u(x,t) = \int_{-\infty}^\infty K(x-y, t)f(y)dy$$

열방정식을 만족시키고, 초기조건도 만족시킴을 확인할 수 있다.

$$ \lim_{t\to 0} \int_{-\infty}^\infty K(x-y, t) f(y)dy = \int_{-\infty}^\infty \delta(x-y) f(y) dy = f(y)$$

 

해의 몇가지 재미있는 특징을 살펴보자. $t=0$일 때 열원이 유한한 영역에서만 0이 아니더라도 $K(x,t>0)$가 0이 아니기 때문에 매우 짧은 시간에 모든 영역으로 열이 퍼져나간다. 즉 열이 퍼지는 속도가 무한대에 해당한다. 열방정식은 비상대론적인 방정식이다. 두 번째로 $t>0$일 때 $K(x-y,t)$가 $x=y$인 지점에서 벗어나는 경우에 매우 빨리 0으로 변하므로 해는 무한번 미분가능하다. 즉, 처음 주어진 온도 분포가 불연속적이더라도 바로 매끄러운 온도분포로 변하게 만드는 특성이 있다. 이 열방정식을 잡음이 들어있는 신호나 영상에 적용하면 smoothing 효과를 줄 수 있다. 그리고

\begin{align}u(\lambda x, \lambda^2 t) &= \int K(\lambda x - y, \lambda ^2 t) f(y)dy \\ &= \int K(\lambda x - \lambda y' , \lambda^2 t )  {\lambda } f(\lambda y') dy' \\ &= \int K(x-y',t)  {\lambda }f(\lambda y') dy' \end{align}

이므로 스케일링된 해는 초기 온도분포가 $\lambda f(\lambda y)$인 경우와 같음을 알 수 있다. 초기에 국소적으로 가열된 경우라면 $\lambda f(\lambda x)$의 분포는 거의 $\delta$ 함수에 접근할 것이므로 충분히 시간이 지나고 먼 거리에서는 온도분포는 초기조건에 무관하게 됨을 알 수 있고, 이는 smoothing 효과로 이해할 수 있다.

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
728x90

'Mathematics' 카테고리의 다른 글

Generalized eigenvalues problem  (0) 2024.03.02
수치적으로 보다 정밀한 이차방정식의 해  (0) 2024.02.23
지구의 나이는?  (0) 2024.02.11
n 차원 공의 부피  (2) 2024.02.07
타원의 둘레길이  (1) 2024.02.06
Posted by helloktk
,