LoginSignup
3
6

More than 3 years have passed since last update.

誤差の少ない微分をしよう!

Last updated at Posted at 2017-12-23

はじめに

今回は、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.
CC0

ソースコードは自由に使用してください。

3
6
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
6