카테고리 없음

c언어로 미분 구현하기

송규 2023. 5. 11. 23:56

이번에 정융탐 주제로 설정하게 된 내용인 미분 구현하기입니다.

수업시간에 미분에 대한 내용을 배우고 나서 극한의 개념을 이용할수 있다면 c언어로 미분의 구현은 할만 하겠다는 생각을 가지게 되었고 간단한 아이디어와 개념을 통해 미분을 구현해보았습니다.

 

평균 변화율이란?

평균 변화율은 함수의 어떤 구간에서의 전체 변화량을 그 구간의 길이로 나눈 값으로, 함수가 해당 구간에서 어떻게 변화하는지를 나타냅니다. 평균 변화율은 두 점 (a, f(a))와 (b, f(b))를 지나는 함수 f(x)의 선분의 기울기와 같은 값으로, 수식으로는 다음과 같이 표현됩니다.

여기서 f(a)는 구간의 시작점에서의 함수값, f(b)는 구간의 끝점에서의 함수값을 의미하고,  b - a는 구간의 길이를 의미합니다. 평균 변화율을 통해 함수가 해당 구간에서 어떻게 변화하는지를 대략적으로 파악할수 있습니다. 하지만 이는 해당 구간에서 함수의 변화율이 항상 일정하다고 가정하는 것이므로, 보다 정확한 변화율을 구하기 위해서는 미분을 이용해 순간 변화율을 구해야 합니다.

그럼 이제 미분에 대해서 알아보겠습니다. 함수의 어떤 한 순간에서의 변화율을 나타내는 개념으로, 함수의 기울기를 계산하는 것입니다. 기본적으로 미분은 함수 f(x)에서 x값이 변할 때, f(x)의 변화량을 x의 작은 변화량인 Δx에 대한 비로 계산하는 것입니다. 이러한 미분값은 x 값이 바뀔 때 함수 f(x)가 얼마나 변화하는지를 나타내는 순간 변화율을 의미합니다. 

 

아래는 미분계수를 정의하는 방법입니다.

저는 미분값을 계산하는 코드를 생각할때 h가 0으로 갈때의 미분계수의 정의를 이용하였습니다.

제가 처음 짠 미분 코드는 다음과 같습니다.

 

#include <stdio.h>
#include <math.h>

	double f(double x) {
  		// 미분할 함수를 정의합니다. 
  	return pow(x, 2)+ x;
	}

	double prime(double x, double h) { // 미분하는 함 
  	return (f(x + h) - f(x)) / h;
	}

	int main() {
 
    	double x; // 미분을 계산할 지점 (극한으로 가까워질 지점) 
  		scanf("%lf", &x);
  		double h = 0.000001; // h의 값 
		    수 
 	 	double dfdx = prime(x, h); // 미분한 결과
  
 			 printf("f'(%.2f) = %.5f\n", x, dfdx); // 결과를 출력합니다. 
 		
	}

위의 코드는 h의 값이 0에 가까울수록 계산한 값이 더욱 정확해지는 특징을 갖습니다. 

코드의 과정은 미분할 함수를 받고 미분을 하는 함수를 만들어서 미분하는 값을 계산하는 코드입니다.

 

근데 이렇게 코드를 짜고 보니 너무 간단한거 같아서 함수를 입력하면 함수의 미분한 함수를 뽑아주는 코드를 추가하기로 했습니다! ^^

제가 미분한 함수를 뽑아주는 코드를 짤때 함수를 작성할때 규칙을 정해서 특정한 기호 ( * )를 기준으로 x의 계수, 지수 등을 구분할수 있겠다라고 생각하였습니다.

위의 말을 토대로 제가 짜본 함수를 미분해주는 코드는 다음과 같습니다. 

\

#include <stdio.h>
#include <string.h>
 
 int main()
 {
 
int d;
    	char a[1000]={};
    	gets(a); // 함수를 입력받는다. 
    	d=strlen(a);// 길이를 측정한다. 
    for(int j=0; j<d; j++)
    {
        if(a[j]=='*') // 미분되는 함수의 꼴이 4*x^5식이므로 *기호를 중심으로 몇칸 움직여서 어떤 값을 나타내는지 확인. 
        printf("%d*x^%d", (a[j-1]-48)*(a[j+3]-48), a[j+3]-49);// *기호를 중심으로 -1칸은 x의 계수, +3칸은 x의 지수를 나타내는 값이다. 이러한 값들을 통해 미분을 나타내었다. 
        if(a[j]=='+') 
        printf("+"); // +기호를 미분한 함수에도 똑같이 붙여줌 
        if(a[j]=='-')
        printf("-"); // - 기호를 미분한 함수에도 똑같이 붙여줌 
    }
}

 이 코드는 함수를 직접 미분하는 코드이고 함수를 입력할때 규칙은 (계수) * x ^ (지수)로 정하고 각각의 계수와 지수를 배열의 인덱스로 선택하였습니다.

 

이제 미분에 대한 코드를 2개 작성했으니 두 코드를 융합해봤습니다.

 

#include <stdio.h>
#include <math.h>
#include <string.h>

	double f(double x) {
  		// 미분할 함수를 정의합니다. 
  	return pow(x, 2)+ x;
	}

	double prime(double x, double h) { // 미분하는 함 
  	return (f(x + h) - f(x)) / h;
	}


 int main()
 {
 
	int d;
    	char a[1000]={};
    	printf("입력할 함수를 (계수)*x^(지수)의 형태로 입력해주세요.\n");
		gets(a); // 함수를 입력받는다. 
    	d=strlen(a);// 길이를 측정한다. 
    for(int j=0; j<d; j++)
    {
        if(a[j]=='*') // 미분되는 함수의 꼴이 4*x^5식이므로 *기호를 중심으로 몇칸 움직여서 어떤 값을 나타내는지 확인. 
        printf("%d*x^%d \n", (a[j-1]-48)*(a[j+3]-48), a[j+3]-49);// *기호를 중심으로 -1칸은 x의 계수, +3칸은 x의 지수를 나타내는 값이다. 이러한 값들을 통해 미분을 나타내었다. 
        if(a[j]=='+') 
        printf("+"); // +기호를 미분한 함수에도 똑같이 붙여줌 
        if(a[j]=='-')
        printf("-"); // - 기호를 미분한 함수에도 똑같이 붙여줌 
    }

 
    	double x; // 미분을 계산할 지점 (극한으로 가까워질 지점) 
  		printf("미분을 계산할 지점을 입력하세요.\n");
		scanf("%lf", &x);
  		double h = 0.000001; // h의 값  
 	 	double dfdx = prime(x, h); // 미분한 결과
  
 			 printf("f'(%.2f) = %.5f\n", x, dfdx); // 결과를 출력합니다. 
 		
	}

 

위의 코드를 직접 실행한 사진

제가 짠 미분 코드의 단점은 미분값을 구할때의 함수는 코드 입력창에서 바꿔야한다는 것입니다.

이부분은 아쉽지만 시간이 없어서 나중에 고쳐보도록 노력해볼 예정입니다..

 

다음은 이 코드의 알고리즘 순서도입니다.