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

#はじめに
今回は、C言語を使って微分するプログラムを作っていきます。

#原理

今回は**"sin(x)"**を微分するプログラムを作っていきます。

```math

f(x) =sin(x)

```

今回、計算する微分の式はこちら。

```math

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

```

**"Δx"**の値は大きすぎても小さすぎても誤差が大きくなってしまうので、誤差が少なくなるような値を代入します。
**"Δx"**の値をこのように設定します。

```math

Δx=1.0^{-8}

```


**"sin(x)"**を微分すると**"cos(x)"**になります。

```math

f'(x) =cos(x)

```

では、実際にどのくらいの誤差でおさまるのか試してみましょう。

#コード
```math
"f(x) =sin(x)" を微分するプログラムです。
```
```c: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|

#誤差
```math
3.4^{-9}
```

なんと誤差の平均は**"3.4の-9乗"**でした！

#C++版

```cpp: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;
	}

}
```

```cpp: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](https://mirrors.creativecommons.org/presskit/buttons/88x31/svg/cc-zero.svg "CC0")](http://creativecommons.org/publicdomain/zero/1.0/deed.ja)

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