오차가 적은 미분을 하자!

소개



이번에는 C 언어를 사용하여 미분하는 프로그램을 만들어 갑니다.

원리



이번에는 "sin(x)"를 미분하는 프로그램을 만들어 갑니다.

f(x) =sin(x)


이번, 계산하는 미분의 식은 이쪽.

f'(x) =\frac{f(x+Δx)−f(x)}{Δx}


"Δx"의 값은 너무 크거나 너무 작아도 오차가 커져 버리므로 오차가 적어지는 값을 대입합니다.
"Δx"의 값을 이렇게 설정합니다.

Δx=1.0^{-8}


"sin(x)"를 미분하면 "cos(x)"가 됩니다.

f'(x) =cos(x)


그럼, 실제로 얼마나 오차로 가라앉는지 시험해 봅시다.

코드


"f(x) =sin(x)" を微分するプログラムです。

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

#define DELTAX 1.0e-8
#define FUNCTION sin(x)
#define PI 3.141592653589793

double f(double x) {
    return FUNCTION;
}

double fd(double x) {
    return (f(x + DELTAX) - f(x)) / DELTAX;
}

int main(){

    int i;
    double x;

    printf("f(x)=sin(X)\n");
    for (i = 0; i < 24; i++) {
        x = i * PI / 12.0;
        printf("|%3d|%.10f|%.10f|%.10f|%.10f|\n", i * 15, fd(x), cos(x), fabs(fd(x) - cos(x)), f(x));
    }

    return 0;
}

결과




학위
f'(x)=cos(x)
[math.h]cos(x)
cos(x) 오차
f(x)=sin(x)


0
1.0000000000
1.0000000000
0.0000000000
0.0000000000

15
0.9659258227
0.9659258263
0.0000000036
0.2588190451

30
0.8660254014
0.8660254038
0.0000000024
0.5000000000

45
0.7071067842
0.7071067812
0.0000000031
0.7071067812

60
0.4999999970
0.5000000000
0.0000000030
0.8660254038

75
0.2588190329
0.2588190451
0.0000000122
0.9659258263

90
0.0000000000
0.0000000000
0.0000000000
1.0000000000

105
-0.2588190440
-0.2588190451
0.0000000011
0.9659258263

120
-0.4999999970
-0.5000000000
0.0000000030
0.8660254038

135
-0.7071067842
-0.7071067812
0.0000000031
0.7071067812

150
-0.8660254014
-0.8660254038
0.0000000024
0.5000000000

165
-0.9659258227
-0.9659258263
0.0000000036
0.2588190451

180
-0.9999999939
-1.0000000000
0.0000000061
0.0000000000

195
-0.9659258171
-0.9659258263
0.0000000092
-0.2588190451

210
-0.8660254014
-0.8660254038
0.0000000024
-0.5000000000

225
-0.7071067731
-0.7071067812
0.0000000081
-0.7071067812

240
-0.4999999970
-0.5000000000
0.0000000030
-0.8660254038

255
-0.2588190440
-0.2588190451
0.0000000011
-0.9659258263

270
0.0000000000
-0.0000000000
0.0000000000
-1.0000000000

285
0.2588190440
0.2588190451
0.0000000011
-0.9659258263

300
0.4999999970
0.5000000000
0.0000000030
-0.8660254038

315
0.7071067842
0.7071067812
0.0000000031
-0.7071067812

330
0.8660254014
0.8660254038
0.0000000024
-0.5000000000

345
0.9659258227
0.9659258263
0.0000000036
-0.2588190451


오차


3.4^{-9}

무려 오차의 평균은 "3.4의 -9승"이었습니다!

C++ 버전



Derivative.hpp
#pragma once
#include <cmath>

namespace math {

    constexpr double delta_x = 1.0 / (double)(1 << 27);
    constexpr double pi = 3.141592653589793;

    double f(const double x) {
        return std::sin(x);
    }

    double fd(const double x) {
        return (f(x + delta_x) - f(x)) / delta_x;
    }

}

Source.cpp
#include <cstdio>
#include "Derivative.hpp"

constexpr double pi_division= math::pi / 12.0;

int main() {
    double x{};
    std::printf("f(x)=sin(X)\n");
    for (int i = 0; i < 24; ++i) {
        x = (double)i * pi_division;
        std::printf("|%3d|%.10f|%.10f|%.10f|%.10f|\n",
            i * 15, math::fd(x), std::cos(x), std::abs(math::fd(x) - std::cos(x)), math::f(x));
    }
    return 0;
}

결론



이번에는 "sin(x)"의 미분을 요구하는 프로그램을 만들었습니다만, 어떠셨습니까?
프로그램으로 미분을 요구할 수 있다는 것은 재미 있군요!

끝까지 읽어 주셔서 감사합니다.

소스 코드 라이센스



These codes are licensed under CC0.
소스 코드는 자유롭게 사용하십시오.

좋은 웹페이지 즐겨찾기