6-2. 練習問題の答え2

なお、導関数がわからなかったり、これを求めるのが困難である場合もある。その場合は、数値微分を計算してみるとうまくいくことがある。1変数関数$f(x)$に対しての微分

$$f^\prime (x)=\lim_{h \to 0}\frac{f(x+h)-f(x)}{h}$$

を、有限の小さな正数 $h$ を用いて

$$f^\prime (x)\approx \frac{f(x+h)-f(x)}{h}$$

によって微分値を近似することになる。丸め誤差に注意が必要であるが、これを用いた結果と、正しい導関数を用いた結果を比較するプログラムとして、たとえば以下のようなものが書ける:

#include <stdio.h>
#include <math.h>
#define eps 1.0e-15
#define xinit 10.0
double f(double x){
  return 2*x*x*x+10.0*x*x-2.0*x-10.0;
}
double fp(double x){
  return 6.0*x*x+20.0*x-2.0;
}
int main(void){
  double x0, x1, f0, fp0;
  double h=1.0e-8;
  x0=xinit;
  do {
    f0=f(x0);fp0=fp(x0);
    x1=x0-f0/fp0;
    x0=x1;
    printf(" %e %e \n", x0, f0);
  }while(fabs(f0)>eps);
  printf("answer: %e \n", x0);
  x0=xinit;
  do {
    f0=f(x0);fp0=(f(x0+h)-f(x0))/h;
    x1=x0-f0/fp0;
    x0=x1;
    printf(" %e %e \n", x0, f0);
  }while(fabs(f0)>eps);
  printf("answer: %e \n", x0);
}

なお、$h$の選び方としては、おおよそ有効桁数の半分程度が良いとされている。