ニュートン-ラプソン法
📂数値解析ニュートン-ラプソン法
メソッド

f,f’,f’’がαの近くで連続であり、f(α)=0,f′(α)=0とする。
αに十分近い初期値x0に対して
xn+1:=xn−f′(xn)f(xn)として定義された数列{xn}は、n→∞の時にαに対してクアドラティックに収束する。
説明
ニュートン-ラフソン法は、ただのニュートン法とも呼ばれる。微分可能性や連続性などの条件があるが、それでも簡単で収束速度が速いため、方程式f(x)=0の近似解を見つけるのに有用な方法である。
クアドラティックに収束するとは、収束率を語る時に2次で収束するという意味だが、適切な翻訳がない。「線形」に収束すると翻訳される1次と比べると、ただの2次で収束するという言葉はあまりにもあいまいで使用例が少ないため、やむを得ず英語表現をそのまま使った。それにもかかわらず、主に二分探索法より収束速度が速いことを数学的に示すことができるため、ここで言及された。
しかし、「αの近く」とか「十分に近い初期値」という表現から分かるように、実際には考えなしに使える方法ではない。0で割る問題が発生するなど不運にも初期値を間違って与えたり、数列自体が解から遠く離れてしまう可能性もある。そのため、解を特定の回数内に求められなかった場合など、計算を諦めるなどの例外処理が必要だ。
このような発散エラーは、数学的に収束性が証明されていても、実際に使う場合は起こりうる問題であり、特にユーザーが「αの近く」や「十分に近い初期値」を正確に把握できないことが原因である。二分探索法が遅くても確実に解を求めてくれるのと比較すると、明らかな欠点だと言える。
一緒に見る
- 高次元に対して一般化されたニュートン-ラフソン法
- ニュートン-フーリエ法: f,f’,f’’が閉区間[a,b]で連続であり、fが[a,b]で増加または減少して解を持つならば、xn+1=xn−f′(xn)f(xn)として定義された数列{xn}は、n→∞の時にαにクアドラティックに収束する。
もう少し強い条件があれば、ニュートン-フーリエ法を考えることができ、収束性が完全に保証されつつクアドラティックに収束する。しかし、この方法は本質的にニュートン-ラフソン法の「αの近く」に閉区間[a,b]を入れたものに過ぎない。したがって、条件をすべてチェックすれば、ニュートン-ラフソン法と完全に同じになり、別のコードを書く必要はない。
証明
戦略: テイラー展開を通じて2次の項を引き出した後、再帰的な不等式を作って収束性を示す。
第1部. テイラー展開
fをxnでテイラー展開すると、xとxnの間のξnに対して
f(x)=f(xn)+(x−xn)f′(xn)+2(x−xn)2f′′(ξn)
f(α)=0なので、x=αを代入すると
0=f(xn)+(α−xn)f′(xn)+2(α−xn)2f′′(ξn)
両辺をf′(xn)で割ると
0=f′(xn)f(xn)+α−xn+2(α−xn)2f′(xn)f’’(ξn)
よってf′(xn)f(xn)−xn=−xn+1だから
0=α−xn+1+2(α−xn)2f′(xn)f’’(ξn)
項を整理すると
α−xn+1=−2f′(xn)f’’(ξn)(α−xn)2
第2部. 収束性
f′はαの近くで連続であり、f′(α)=0があるので、すべてのx∈Iδに対してf′(x)=0を満たすIδ:=[α−δ,α+δ]が存在する。
M(δ):=2minx∈Iδ∣f′(x)∣maxx∈Iδ∣f′′(x)∣と置くと、δを小さくするたびに、x∈Iδmax∣f′′(x)∣は増加せず、x∈Iδmin∣f′(x)∣は減少しないので、M(δ)全体は増加しない。したがって、M(δ)∣α−x0∣<1が成り立つような十分に小さなδ=δ0を選べる。まさにこのx0がαに十分近い初期値である。
このδ0について、今M:=M(δ0)としよう。
(1)の両辺に絶対値をとると
∣α−xn+1∣≤M∣α−xn∣2
両辺にMを掛けると
M∣α−xn+1∣≤M2∣α−xn∣2
右辺を二乗でまとめると
M∣α−xn+1∣≤(M∣α−xn∣)2
この過程をxn+1からx0が出るまで繰り返すと
M∣α−xn+1∣≤(M∣α−xn∣)2≤(M∣α−xn−1∣)4≤⋯≤(M∣α−x0∣)2n+1
整理すると
∣α−xn∣≤M1(M∣α−x0∣)2n
M∣α−x0∣<1なので、n→∞の時にxn→α
第3部. クアドラティックに収束
(1)により、(α−xn)2α−xn+1=−2f′(xn)f’’(ξn)であり、xn→αの時にξn→αなので
n→∞lim(α−xn)2α−xn+1=−n→∞lim2f′(xn)f′′(ξn)=−2f′(α)f′′(α)
■
説明で収束性が常に保証されるわけではないと話したが、実際に十分に小さなIを選ぶことが重要である。
実装

以下はRで書かれたコードだ。df
を導関数として入れれば、導関数を直接計算し、省略すれば微分係数を別に求めて使う。itmax
オプションは最大で繰り返す回数で、デフォルトで1000回繰り返しても十分な精度の解が得られなければ、計算を諦める。
d<-function(f,x,tol=10^(-8))
{
h<-1
d1<-1
d2<-0
while(abs(d1-d2)>tol)
{
d1<-d2
d2<-(f(x+h)-f(x))/h
h<-h/2
}
return(d2)
}
Newton<-function(f,x0,df=FALSE,itmax=10^3,tol=10^(-8))
{
if(f(x0)==0){return(x0)}
denom=0
x1 = x0 - f(x0)/d(f,x0)
for(i in 1:itmax)
{
if(is.function(df)){
denom=df(x1)
}else{
denom=d(f,x1)
}
if(denom==0){stop('Zero Derivative\')}
x2 = x1 - f(x1)/denom
if(abs(x2-x1)<tol){
return(x2)
}else{
x1 = x2
}
}
stop('Maybe Wrong Initial Point')
}
f<-function(x) {x^3 + 8}
Newton(f,7)
g<-function(x) {x^6 - x - 1}
Newton(g,3)
h<-function(x) {exp(x)-1}
Newton(h,-2)