본문 바로가기

학습공간/수치해석, 확률과통계, 이산수학

[C언어 수치해석] 직사각형 방법, 사다리꼴 방법, Simpson 방법 (수치적분)

반응형

[개념설명]

 

1) 직사각형 방법

직사각형 방법f(x)의 a~b구간을 n등분 하여 각 구간의 밑변을 h로 하고 그때의 함수 값을 높이로 하여 n개의 직사각형 넓이를 모두 더하는 방법이다. 단점은 f(x)가 급격히 변화하는 그래프라면 정적분과의 오차가 심하게 난다는 것이다.

 

2) 사다리꼴 방법

사다리꼴 방법f(x)의 a~b구간을 n등분 하여 각 구간의 밑변을 h로 하고 그때의 함수 값을 높이로 하여 n개의 사다리꼴 넓이를 모두 더하는 방법이다. 직사각형 방법의 비효율을 사다리꼴을 통해 줄여주기 때문에 굉장히 효율적이지만, 역시나 f(x)가 곡선 그래프일 경우 어느 정도 오차가 발생한다.

 

3) Simpson 방법

Simpson 방법f(x)의 a~b구간을 n등분(n=짝수) 하여 각 구간의 밑변을 h로 하되 2h구간씩 잡고 첫 번째 점, 중점, 마지막 점 이렇게 3개의 점으로 2차 곡선 g(x)를 구해, 각 g(x)를 적분한 값을 n/2 번 더해주는 방법이다.

이 방법은 f(x)가 곡선 그래프의 경우에도 각 구간(2h)당 g(x)가 2차 곡선 그래프이므로, 사다리꼴 방법에서 생겨난 오차조차도 커버해주기 때문에 전체적으로 오차가 거의 없다.

 

직사각형 방법
사다리꼴 방법
Simpson 방법

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// 직사각형 방법
#include <stdio.h>
#include <math.h>
#define r 3.141592/180
double f(double x){
    return exp(x)*sin(x);
}
double Fc(double x){
    return (1/2.0)*(exp(x)*sin(x)-exp(x)*cos(x));
}
double F(double x, double y){
    return Fc(y)-Fc(x);
}
void main()
{
    int n=2,k;
    double V1, sum1=0;
    double a=1, b=3// 정적분 구간 (각도)
    a=a*r; b=b*r;    //        (라디안)
    
    while(1){
 
    double h = (b-a)/n;
 
    for(k=0; k<n; k++)
    {
        sum1 += f(a+k*h);
    }
    
    V1 = h*sum1;
 
    if(fabs(F(a,b)-V1) <0.000001){    // 오차 10^-6
        printf("정적분 값 : %lf\n",F(a,b));
        printf("직사각형방법 = %lf \nn=%d\n",V1,n);
        break;
    }
    n++;
    sum1 = 0;
    }
}
 
// 사다리꼴 방법
#include <stdio.h>
#include <math.h>
#define r 3.141592/180
double f(double x){
    return exp(x)*sin(x);
}
double Fc(double x){
    return (1/2.0)*(exp(x)*sin(x)-exp(x)*cos(x));
}
double F(double x, double y){
    return Fc(y)-Fc(x);
}
void main()
{
    int n=2,k;
    double V1, sum1=0;
    double a=1, b=3// 정적분 구간 (각도)
    a=a*r; b=b*r;    //        (라디안)
    while(1){
 
    double h = (b-a)/n;
 
    for(k=1; k<n; k++)
    {
        sum1 += 2*f(a+k*h);
    }
    
    V1 = h/2*(f(a)+sum1+f(b));
 
    if(fabs(F(a,b)-V1) <0.000001){    // 오차 10^-6
        printf("정적분 값 : %lf\n",F(a,b));
        printf("사다리꼴방법 = %lf \nn=%d\n",V1,n);
        break;
    }
    n++;
    sum1 = 0;
    }
}
 
// Simpson 방법
#include <stdio.h>
#include <math.h>
#define r 3.141592/180
double f(double x){
    return exp(x)*sin(x);
}
double Fc(double x){
    return (1/2.0)*(exp(x)*sin(x)-exp(x)*cos(x));
}
double F(double x, double y){
    return Fc(y)-Fc(x);
}
void main()
{
    int n=2,k;
    double V1, sum1=0;
    double a=1, b=3// 정적분 구간 (각도)
    a=a*r; b=b*r;    //        (라디안)
    while(1){
 
    double h = (b-a)/n;
 
    for(k=0; k<=n/2-1; k++)
    {
        sum1 += f(a+2*k*h)+ 4*f(a+(2*k+1)*h)+ f(a+(2*k+2)*h);
    }
    
    V1 = h/3*sum1;
    
    if(fabs(F(a,b)-V1) <0.000001){    // 오차 10^-6
        printf("정적분 값 : %lf\n",F(a,b));
        printf("Simpson방법 = %lf \nn=%d\n",V1,n);
        break;
    }
    n=n+2;
    sum1 = 0;
    }
}
cs

위의 출력 결과 화면을 보면 같은 수식 f(x) = e^x * sin(x)

직사각형 방법, 사다리꼴 방법, Simpson방법을 통해 오차 10^-6이내에 n등분의 n을 구해 보았는데 똑같은 수식이지만 직사각형 방법은 653, 사다리꼴 방법 3, Simpson 방법 2 로

효율성 면에서 직사각형 < 사다리꼴 < Simpson 순으로 나타났다.

 

반응형