카테고리 없음

정보과학 계획서 - 미분방정식 방향장 생성 프로그램 배경적 지식의 구체화

임대현 2024. 5. 12. 21:34

 

1. 연구에 필요한 구체적 지식

 

가. 수학적 배경 지식

 

1). 미분방정식의 형태에 대한 구체적 학습

 

미분방정식의 형태는 매우 다양하다. 대표적인 미분방정식만 하더라도 변수분리형 미분방정식, 1차선형미분방정식, 2차선형미분방정식, 코시-오일러 방정식 등 다양한 형태가 존재한다. 이러한 다양한 미분방정식의 형태들 중 프로세싱을 통하여 방향장과 개형을 그릴 수 있는 형태들을 선별하여 프로그램을 통해 구현하고자 한다. 방향장을 좌표평면에 그리기 쉬운 미분방정식은 최대 미분 횟수가 1회인 1계 미분방정식이므로 이들의 방향장을 그리는 것을 목표로 한다.

 

2). 방향장에 대한 구체적 학습

 

방향장은 미분방정식의 해를 구할 때 사용되는 그래프의 일종이다. 일계 미분방정식 dy/dx=g(x,y)를 생각해 보자. 이 미분방정식을 좌변에 미분계수가 존재하며, 우변에 x, y에 대한 식이 존재하는 평범한 식이라고 생각할 수도 있지만 다르게 생각해 보면 주어진 함수의 특정 점에서의 접선의 기울기를 나타내고 있는 식이라고 생각할 수 있다. 따라서 주어진 dy/dx=g(x,y) 형태의 미분방정식에서 x, y 좌표를 안다면 이를 통해 주어진 점에서의 접선의 기울기를 구할 수 있다. 이를 평면의 각 격자점마다 격자점에서의 접선 방향으로 짧게 화살표를 그려 준 것이 방향장(Direction Field) 이다. 방향장은 시각적으로 미분방정식의 해곡선의 개형을 국소적으로 알 수 있게 해 준다. 따라서 미분방정식의 초깃값 문제에서 초깃값을 하나 안다면 방향장을 통해 그 초깃값에서의 접선의 기울기를 찾고 이를 연속적으로 연결해 감으로써 미분방정식의 특수해의 대략적인 개형을 알 수 있게 된다.

 

3). 선형근사법에 대한 구체적 학습

 

오일러의 방법(Euler’s Method)은 함수의 선형근사를 이용하여 미분방정식의 해를 수치적으로 근사시키는 방법이다. 구해낸 방향장으로부터 방정식의 해곡선을 찾아내는 과정을 오일러의 방법에 응용할 수 있다.

 

함수 y=f(x)에 대해 이 함수 위의 한 점 P(a,f(a)) 에서의 접선의 방정식은 다음과 같다.

 

y-f(a) = f'(a)(x-a)

 

곡선 위의 미분 가능한 한 점 근방의 국소적인 구간에서 곡선은 미분 가능한 곡선 위 점에서의 접선으로 선형 근사 가능하다. 이를 이용하여 도함수를 안다면 함수의 개형을 대략적으로 구할 수 있다. 따라서 점 x=a 근방에서 함수는 직선 y-f(a) = f'(a)(x-a) 로 근사된다. 이러한 근사법은 x=a 근방에서는 유효한 근삿값을 제공하나, x=a 로부터 멀어질수록 그 정확성이 낮아져 유효하지 않은 값이 도출되게 된다.

 

오일러의 방법은 이러한 선형근사법을 개선한 것이다. 개형을 구해야 할 함수를 여러 구간으로 쪼갠 뒤 각 구간에서의 선형근사 식을 따로 구해 이들을 모두 합쳐 특수해의 근사해를 구하는 것이다. 이러한 오일러의 방법을 통해 얻어지는 근사해를 조각적 선형함수라고 한다. 구간의 크기가 작아질수록, 즉 더 촘촘하게 선형근사 식을 구할수록 더 정확한 근사해를 얻을 수 있게 된다.

 

나. 정보과학 배경 지식

 

1). 반복문에 대한 구체적 학습

 

방향장의 모습과 미분방정식의 해의 대략적인 개형을 구하기 위한 방법으로, 반복문을 이용하는 방법을 생각해 볼 수 있다. 좌표평면을 x좌표와 y좌표로 일정한 간격으로 분할한 뒤 각 격자점에서의 접선의 기울기를 계산한다. 이중 반복문을 통해 해당 과정을 반복한 뒤 구해낸 접선의 기울기를 화살표를 통하여 표시해 주면 방향장을 시각적으로 표현 가능하다고 생각할 수 있다.

미분방정식의 오일러 방법을 통한 근사해를 그리는 경우는 조금 다른 방법을 통하여 구해낼 수 있다. 먼저, 미분방정식에 그려진 초깃값에서의 접선의 방정식을 구한다. 그 후 오일러의 방법대로, 적당한 크기로 구간을 분할한다. 그 후 초깃값보다 더 작은 x좌표를 가지는 구간부터 순차적으로 접선의 방정식의 각 구간의 끝점에서 새로운 접선의 방정식을 구하는 방식을 통해 미분방정식의 특수해의 개형을 그려낸다. 그 후 초깃값보다 더 큰 x좌표를 가지는 구간도 마찬가지로 같은 방법을 통해 연속적으로 접선의 방정식을 각 구간마다 조각적으로 구해 미분방정식의 특수해의 개형을 그려낸다. 반복문을 통해 매 구간의 시작점의 좌표를 일정 간격으로 늘리거나 줄여 가며 해당 과정을 완료할 수 있을 것으로 예상된다.

 

2). 자료 입력 방식에 대한 구체적 학습

 

미분방정식은 그 형태가 매우 다양하다. 이러한 수많은 형태의 미분방정식들을 모두 그 형태에 맞추어 분류해 생성해 주는 프로그램을 제작하기는 현실적으로 무리가 있으며, 자료를 입력받기에도 힘들어진다. 따라서 이를 해결하기 위해 프로세싱을 이용하여 미분방정식을 입력받을 때 미분방정식의 형태를 하나로 통일시킨 뒤 입력받을 계획이다.

미분방정식의 변수는 x,y 2개로 지정하여 평면 위에 방향장과 미분방정식을 표현할 수 있도록 한다. 미분방정식의 형태는 dy/dx=g(x,y) 형태로 지정하여 x,y 값에 따라 dy/dx 값을 계산하여 방향장을 작성할 수 있도록 한다. 

 

3). 자료 출력 방식에 대한 구체적 학습

 

본 연구의 목적은 미분방정식의 방향장과 미분방정식의 근사해를 구해낸 뒤 이를 시각적으로 표현해 보여줌으로써, 초깃값이 주어졌을 때 미분방정식의 해의 대략적인 개형을 그려낼 수 있게 하는 것이다. 따라서 자료 출력 방식은 좌표평면 위에 방향장과 조각적 선형근사 방정식의 개형을 표현해 주는 것이다. 프로세싱은 기본적으로 좌표평면을 이용하여 결과물을 출력하므로 프로세싱은 해당 연구의 결과를 출력하기에 적합한 프로그램이라고 볼 수 있다.

 

. 프로세싱 배경지식

 

1). 연구에 필요한 함수, 기능

 

본 연구에 필요할 함수나 기능들을 생각해 보자. 먼저, 프로세싱의 기본적인 좌표 시스템은 화면 왼쪽 최상단을 원점으로 하여 오른쪽이 +x 방향, 아래가 +y 방향이다. 그러나 실제 적용할 좌표평면은 화면 중앙이 원점, 오른쪽이 +x 방향, 위쪽이 +y 방향이다. 만약 좌표평면이 이와 같이 설정된 상태에서 방향장을 그리려 한다면 좌표 계산이 매우 힘들 것이며 착오가 발생할 수도 있다. 그러나 프로세싱에서는 좌표 설정을 바꿀 수 있는 기능을 제공한다. translate(x,y) 함수를 이용하면 주어진 x, y 좌표 값만큼 좌표평면 자체가 이동되게 된다. 따라서 모든 작업을 시작하기 전에 translate 함수를 이용해 좌표평면의 원점을 화면 중심으로 이동시킨 뒤 시작한다. y축의 방향의 경우, 프로세싱에서 좌표평면을 대칭변환 시켜주는 함수는 존재하지 않는 것으로 보여, 실제 좌표평면과 일치하도록 설정하지 못 할 것으로 예상된다. 따라서 y좌표의 경우는 원래 좌표에 음수 부호를 붙인 값으로 계산하여 작업을 진행하도록 한다.

 

두 번째로, 기본적인 도형 함수들이다. background(r,g,b) 함수를 통하여 배경 색을 설정 가능하다. 기본적으로 백색으로 설정해 두도록 하자. fill(r,g,b), stroke(r,g,b) 함수를 통하여 도형의 내부 색과 윤곽선 색을 설정 가능하다. line(x1,y1,x2,y2) 함수를 이용하여 선분을 그릴 수 있다. 이를 이용하여 x축과 y축을 그릴 수 있다. rect(x,y,width,height), ellipse(x,y,width,height) 함수를 이용하여 직사각형을 그릴 수 있다. 이를 통하여 제작할 프로그램의 기본적인 인터페이스를 제작할 수 있다.

 

세 번째로, 입력 함수이다. 프로그램의 목적은 사용자가 원하는 미분방정식의 방향장과 그 특수해를 그려 주는 것이다. 따라서 구해야 할 미분방정식의 수식과 특수해를 사용자로부터 입력받을 필요가 있다. 수식과 값을 입력받는 가장 쉬운 방법은 키보드를 이용한 방법일 것이다. 프로세싱은 키보드를 통하여 값을 입력받을 수 있는 함수를 지원한다. keypressed() 함수는 키보드를 인식해 주는 함수이다. keypressed() 함수를 통해 인식된 입력값은 key라는 변수에 저장된다. keypressed() 함수를 이용해 사용자가 입력한 함수와 초깃값을 화면에 표시함과 동시에 그 식과 초깃값을 저장하여 접선의 기울기 값 계산에 이용 가능하다.

 

네 번째로, 반복문이다. 방향장과 그래프 개형을 그리기 위해서는 각 좌표값에 해당하는 접선의 기울기, 각 구간에 해당하는 선형 방정식을 연속하여 그려 주어야 하므로 반복문을 필수적으로 사용해야 한다. 프로세싱의 반복문은 if, while문이 존재한다. 이중 for문을 이용한 반복문이 방향장 생성에 제일 효과적일 것으로 예상된다.

 

2). 프로세싱에서의 자료 입력

 

C, python 등 다른 언어를 사용하여 프로그램을 제작하였을 경우에는 키보드를 통하여 입력받아야 하는 자료를 쉽게 전달할 수 있었다. 그러나 프로세싱의 경우 추가적인 함수를 통하여 키보드 정보를 입력받아야 한다. 이는 위에서 소개한 keypressed() 함수를 이용하여 입력받을 수 있다. 이를 이용하여 사용자료부터 방향장과 개형을 파악하고 싶은 미분방정식과 그 초깃값을 입력받을 수 있을 것이다.

 

3). 프로세싱에서의 결과 출력

 

프로세싱에서 보여주고자 하는 결과를 출력하는 방법은 여러 가지가 존재한다. 먼저, 기본적인 출력화면의 좌표평면을 이용하여 출력하는 방법이 있다. 이 방법을 이용할 경우 방향장에 그릴 화살표 등 다양한 도형을 쉽게 표현 가능한 장점이 존재한다. 그러나 매 프레임마다 새로운 요소를 기존 프레임에 존재하던 이미지에 덮어 씌우는 방식이므로 만약 초기 시작 화면을 실행 화면과 따로 제작할 시 두 화면 간의 전환이 힘들 수 있다는 단점이 존재한다.

 

또 다른 방법으로는 pixel을 이용할 수 있다. pixelprocessing에서 제공하는 함수의 일종이다. pixel을 통하여 출력 화면을 픽셀로 표현 가능하다. pixel은 프로세싱 내장 함수이기 때문에 배열 선언을 하지 않고도 사용 가능하다. loadPixels() 함수는 픽셀 배열에 접근함을 알리는 함수이며 updatePixels() 함수는 픽셀 배열 접근이 끝났음을 알리는 함수이다. 배열의 접근과 마찬가지로 pixels 배열의 가로 x번째, 세로 y번째 픽셀은 다음 식을 통하여 접근 가능하다.

 

pixels[x+y*width]

 

pixel을 사용한다면 좌표평면 위에 시각적 이미지를 표시할 때 기본으로 제공되는 프로세싱 화면보다 더 체계적으로 표현 가능하며, 반복문을 이용한 작업이 용이하다는 장점이 존재한다. 그러나 pixel을 통해서는 화살표 등 픽셀로 표현하기 힘든 도형들을 화면 위에 그리기 어려울 것이라는 단점이 예상된다.

 

프로세싱이 기본적으로 제공하는 출력 화면과 pixel을 이용한 출력 화면의 장단점을 종합적으로 비교해 본 결과, 방향장의 핵심 표현인 접선의 기울기를 화살표로 표현하는 것이 기본 제공 출력 화면이 더 유리하므로 기본 제공 출력 화면을 방향장 이미지 출력에 사용하는 것이 적절할 것으로 판단되었다.

 

2. 연구 지식 학습 결과물

 

. 간단한 미분방정식을 오일러의 방법을 이용해 근사해 구하기

 

미분방정식
dy/dx = 2x
초깃값
(2,1)
오일러 방법으로 구해 낸 조각적 선형함수
y=-2 {0<=x<=0.5}

y=x-2.5 {0.5<=x<=1}

y=2x-3.5 {1<=x<=1.5}

y=3x-5 {1.5<=x<=2}

y=4x-7 {2<=x<=2.5}

y=5x-9.5 {2.5<=x<=3}

y=6x-12.5 {3<=x<=3.5}

y=7x-16 {3.5<=x<=4}

y=8x-20 {4<=x<=4.5}

y=9x-24.5 {4.5<=x<=5}
실제 미분방정식의 해
y=x^2-3
함수의 개형 비교

 

 

. 프로세싱을 이용하여 함수의 그래프 그리기

 

float x,y1,y2;
void setup() {
translate(500,500);
background(255);
fill(0);
size(1000,1000);
line(-500,0,500,0);
line(0,500,0,-500);
}
 
void draw() {
translate(500,500);
for(x=-500 ; x<=500 ; ++x)
{
y1=0.01*x*x;
y2=0.01*(x+1)*(x+1);
line(x,-y1,x+1,-y2);
}
}

 

 

. 프로세싱에서 키보드를 통해 문자 입력받기

 

void setup() {
background(255);
textSize(50);
size(1000,1000);
}
 
void draw() {
stroke(0);
}
 
void keyPressed() {
fill(0);
background(255);
translate(500,500);
text(key,0,0);
}

 

 

. 프로세싱에서 키보드를 통해 문장 입력받기

 

String str = "";
 
void setup() {
background(255);
textSize(75);
size(1000,1000);
}
 
void draw() {
}
 
void keyPressed()
{
translate(500,500);
fill(0);
background(255);
if (key == ENTER)
{
str = "";
return;
}
str += key;
text(str, 0, 0);
}