contents

2.4

f(λ) = -1 + λ + λ2 (1)
f'(λ) = 1 + 2λ (2)

式(1)のグラフをFig. 2.4に示す。
a graph of eq.(1) is shown in Fig. 2.4.

Fig. 2.4

Hand calculation

λ0 = 1 ( >0 )

f(λ0) = -1 + 1 + 12 = 1
f'(λ0) = 1 + 2(1) = 1 + 2 = 3
λ1 = λ0 - f(λ0) / f'(λ0) = 1 - 1 / 3 = 2/3

f(λ1) = -1 + 2/3 + (2/3)2 = -1 + 2/3 + 4/9 = 1/9
f'(λ1) = 1 + 2(2/3) = 1 + 4/3 = 7/3
λ2 = λ1 - f(λ1) / f'(λ1) = 2/3 - (1/9) / (7/3) = 13/21

f(λ2) = -1 + 13/21 + (13/21)2 = 1/212
f'(λ2) = 1 + 2(13/21) = 47/21
λ3 = λ2 - f(λ2) / f'(λ2) = 13/21 - (1/212) / (47/21) = 610/987

f(λ3) = -1 + 610/987 + (610/987)2 = 1/9872
f'(λ3) = 1 + 2(610/987) = 2207/987
λ4 = λ3 - f(λ3) / f'(λ3) = 610/987 - (1/9872)/(2207/987) = 1346269/2178309

∴λ0 = 1
 λ1 = 2/3 (=0.667)
 λ2 = 13/21 (=0.619)
 λ3 = 610/987 (=0.618)
 λ4 = 1346269/2178309 (=0.618)

Newton法の収束の様子をFig. 2.4.2に示す。
Fig. 2.4.2 Newton's method


Maxima

Maximaによる解を次に示す。(added on 2016-11-05)

Maximaによる解は、Hand calculationによる解と一致した。


%i Maxima に対する手入力。
%o Maxima による出力。
%i1 関数 f(x) を定義(:=)する。
%i3 変数 x0 に 1 を代入(:)する。


Maxima 5.38.1 http://maxima.sourceforge.net
using Lisp SBCL 1.3.4
Distributed under the GNU Public License. See the file COPYING.
Dedicated to the memory of William Schelter.
The function bug_report() provides bug reporting information.
(%i1) f(x)  := -1 + x + x ^ 2;
                                                 2
(%o1)                       f(x) := (- 1) + x + x
(%i2) fd(x) := 1 + 2 * x;
(%o2)                          fd(x) := 1 + 2 x
(%i3) x0 : 1;
(%o3)                                  1
(%i4) x1 : x0 - f(x0) / fd(x0);
                                       2
(%o4)                                  -
                                       3
(%i5) x2 : x1 - f(x1) / fd(x1);
                                      13
(%o5)                                 --
                                      21
(%i6) x3 : x2 - f(x2) / fd(x2);
                                      610
(%o6)                                 ---
                                      987
(%i7) x4 : x3 - f(x3) / fd(x3);
                                    1346269
(%o7)                               -------
                                    2178309
(%i8)


f(x)=0の根を「探索」で求める

added on 2016-11-13.
二分法(bisection method)で方程式の根を求める方法が、二分探索(binary search) に似ているので、探索の手法で方程式の根を求めるプログラムを作成した。

f(x)を次式とする。

f(x) = x2 + x - 1

区間[0, 1]において、間隔0.001毎にxとf(x)を計算し、表を作成する。 間隔0.001は、方程式の根を小数点以下3桁まで求めるために設定した。

i01i9991000
xi00.001xi0.9991
f(xi)0-0.998999f(xi)0.9970011

逐次探索(sequential search)

上表のデータを次で作成する。(in Python 3)


x_table  = list(map(lambda x: x / 1000, range(1001))) # 0.000 to 1.000 step 0.001
f_table  = list(map(lambda x: f(x),  x_table))
fd_table = list(map(lambda x: fd(x), x_table))

次の関数でリストtab、f(xi)のリスト、の個々の要素を順番に調べていって、 f(xi) が 0 の要素を探索する。
ただし、f(xi) が 0 である要素がない場合は、 f(xi)の絶対値が最小になる xi を方程式の根とする。
関数 lookup_a(tab) は、リストtab のインデックス i と探索した回数 n をリスト [i, n]で返す。


# sequential search
def lookup_a(tab):
  n = 0
  if tab[0] < 0:
    for i in range(len(tab)):
      n = n + 1
      if tab[i] >= 0:
        break
  if tab[0] > 0:
    for i in range(len(tab)):
      n = n + 1
      if tab[i] <= 0:
        break
  if tab[0] == 0:
    return [0, n]

  if abs(tab[i-1]) < abs(tab[i]):
    return [i-1, n]
  else:
    return [i, n]

二分探索(binary search)

次の関数では、リストtab、f(xi)のリスト、 の最初の要素のインデックスを low とし、最後の要素のインデックスを high とし、 二分探索をリストtabに適用する。
探索中に low + 1 = high になった場合は、 f(xi) の絶対値の小さい方を根とする。
関数 lookup_b()は、リストのインデックス i と探索した回数 n をリスト[i, n]で返す。


# binary seaarch
def lookup_b(tab):
  n = 0
  low = 0
  high = len(tab) - 1
  while low <= high:
    n = n + 1
    mid = int((low + high) / 2)
    cmp = tab[mid]
    print('{:2d}{:4d}{}{:}'.format(n, mid, ' ',cmp))
    if cmp > 0:
      high = mid
    elif cmp < 0:
      low = mid
    else:
      return [mid, n]
    if low + 1 == high:
      if abs(tab[low]) < abs(tab[high]):
        return [low, n]
      else:
        return [high, n]

Newtonの方法

次のプログラムは、Newtonの方法を上の数表に適用したものである。 小数点以下3桁が変化しなくなることを収束条件とした。


# Newton's search
def lookup_c(x_tab, f_tab, fd_tab):
  n = 0
  if f_tab[len(f_tab)-1] > 0:
    i1  = len(f_tab) - 1
    n = n + 1
    x2 = x_tab[i1] - f_tab[i1] / fd_tab[i1]
    while 1:
      x2 = round(x2, 3)
      i2 = x_tab.index(x2)
      print('{:10d}{:10d}{:10d}{:15.3f}'.format(n,i1,i2,x2))
      if i1 == i2:
        return [i, n]
      i1 = i2
      n = n + 1
      x2 = x_tab[i1] - f_tab[i1] / fd_tab[i1]
  return [i, n]

探索結果

探索結果を次に示す。

逐次探索は620回、二分探索は10回、 Newtonの方法は4回で小数点以下3桁までの根が探索された。


sequential search result
    n    i     x_table[i]               f_table[i]
--------------------------------------------------
  620  618          0.618   -7.599999999996498e-05
--------------------------------------------------

binary search
n i   f(x)
------------------------------
 1 500 -0.25
 2 750 0.3125
 3 625 0.015625
 4 562 -0.12215599999999993
 5 593 -0.05535100000000004
 6 609 -0.020118999999999998
 7 617 -0.002310999999999952
 8 621 0.006641000000000119
 9 619 0.0021610000000000795
10 618 -7.599999999996498e-05
------------------------------

binary search result
    n    i     x_table[i]               f_table[i]
--------------------------------------------------
   10  618          0.618   -7.599999999996498e-05
--------------------------------------------------

Newton's search
         n        i1        i2     x_table[i]
---------------------------------------------
         1      1000       667          0.667
         2       667       619          0.619
         3       619       618          0.618
         4       618       618          0.618
---------------------------------------------

Newton's search result
    n    i     x_table[i]               f_table[i]
--------------------------------------------------
    4  618          0.618   -7.599999999996498e-05
--------------------------------------------------

探索プログラム

2.4b.py

注、逐次探索と二分探索の部分は、次を見て作成した。

Brian W.Kernighan, Rob Pike, 福崎俊博 訳、プログラミング作法、株式会社アスキー、2000、pp.54-56 、ISBN4-7561-3649-4.


Python 3 code

2.4.py

Fortran code

revised on 201-03-26, 2025-02-01 open revised 2.4.f90

2.4.f90

Gauche code

revised on 201-03-26, 2025-02-01 open revised 2.4.scm

2.4.scm

JavaScript code

added on 2016-02-06, 2025-02-01 open revised 2.4.js

2.4.js

Julia code

コードを次のリンクに示す。

2.4.jl

備考 Fig. 2.4他について
Note, about Fig. 2.4 and so on

(added on 2005-2-14, revised on 2011-10-29.)
Fig.2.4は、次を使用して作成した。
Fig. 2.4 was made with the following.

GNUPLOT
Version 4.4 patchlevel 3
last modified March 2011
System: MS-Windows 32 bit
Copyright (C) 1986-1993, 1998, 2004, 2007-2010
Thomas Williams, Colin Kelley and many others

図化コマンドを次のリンクに示す。


history

revised on 2005-2-14, 2007-04-21, 2008-02-19, 2009-08-09, 2011-10-26, 2011-11-02, 2014-02-11, 2015-03-28, 2016-02-06, 2016-03-26, 2016-09-28, 2016-10-23, 2016-10-30.
2016-09-28 Fortarn, Gauche, Javascript codes moved to link.
2016-10-23 Fig. Newton's method added.
2016-10-30 Python code and gnuplot script moved to link.
2016-11-05 solution by Maxima added.
2016-11-13 solution in search way added.
2018-01-01 png changed to svg.
2018-01-03 XHTML1.0 changed to HTML5.
2018-06-03 charset shift-jis to utf-8.
2021-02-14 move history.
2024-08-28 revise 2.4.js.
2024-10-26 add 2.4.jl.
2025-02-01 open revised 2.4.f90, 2.4.scm, and 2.4.js.


contents