song.yz@foxmail.com wechat: math-box

计算数学





重根迭代改进

Newton迭代法在处理重根运算时候往往效果不是太好, 有时候收敛速度会非常的慢。为了处理这一问题,往往我们需要对迭代法进行一些改造。

如果采取以下的迭代方法,计算效果会很不错,但是需要计算二次导数。 \[{x_k} = {x_{k - 1}} - \frac{{F({x_{k - 1}})}}{{F'({x_{k - 1}})}}\] 其中 \[F(x) = \frac{{f(x)}}{{f'(x)}}\] 展开上式,便得到迭代公式 \[{x_k} = {x_{k - 1}} - \frac{{f({x_{k - 1}})f'({x_{k - 1}})}}{{{{[f'({x_{k - 1}})]}^2} - f({x_{k - 1}})f''({x_{k - 1}})}}\] 这就是重根时的改进迭代格式。

用重根迭代改进方法计算方程 \[f(x) = {x^4} - 4{x^2} + 4 = 0\] 在\(x=1.5\)附近的根。 下面给出go语言代码。


// multiroot
package main
import (
	"fmt"
	"math"
)
func main() {
	/*------------------------------------------------------
	!  Author  : Song Yezhi      
	!  verison : 2020-5-18 10:29
	!  -----------------------------------------------------
	!  Input  Parameters :
	!
	!  Output Parameters :
	!
	------------------------------------------------------*/
	var x0 float64 = 1.5    
    fmt.Printf("newton result: \n")
	_, _  = newton(x0)
	fmt.Printf("-------------- \n")	
	fmt.Printf("multiroot iter : \n")
	_, _  = multiRoot(x0)
}

func funcX(x float64) float64 {
	/*------------------------------------------------------
	  !  Author  : Song Yezhi      
	  !  verison : 2021.10.04
	  !
	  ------------------------------------------------------*/
	fx := math.Pow(x,4)-4*x*x+4
	return fx
}
func dfuncX(x float64) float64 {
	/*------------------------------------------------------
	!  Author  : Song Yezhi      
	!  verison : 2020-5-18 10:29
	!
	------------------------------------------------------*/
	df := 4.0*x*x*x - 8.0*x 
	return df
}
func d2funcX(x float64) float64{
    /*------------------------------------------------------
     Author  : Song Yezhi                       
     verison : 2021-10-4 18:04
     go build -gcflags "-N -l"  
     
    ------------------------------------------------------*/
    d2f:=12.0*x*x-8.0
    return d2f    
}
func newton(x0 float64) (x1, fx float64) {
	/*------------------------------------------------------
	!  Author  : Song Yezhi      
	!  verison : 2020-5-18 10:30
	!      牛顿法计算方程根
	!  -----------------------------------------------------
	!  Input  Parameters :
	!       x0-----初值
	!  Output Parameters :
	!        
	-------------------------------------------------------*/
	var imax int = 20
	var tol float64 = 1e-8
	for i := 0; i < imax; i++ {
		x1 = x0 - funcX(x0)/dfuncX(x0)
		fx = funcX(x0)
		dfx := dfuncX(x0)
		x1 = x0 - fx/dfx
		dx := math.Abs(x1 - x0)
		if dx < tol {
			break
		}
		x0 = x1
		fmt.Printf("i= %4d  x= %12.7f  f(x)=%12.7f \n", i, x1, fx)
	}
	return
}
func  multiRoot(x0 float64)(x1,fx float64){
/*------------------------------------------------------
  Author  : Song Yezhi                       
  verison : 2021-10-4 18:08
  go build -gcflags "-N -l"  
     
  -----------------------------------------------------  
  Input  Parameters :
     x0  --- 初值
  Output Parameters : 
     x1----- 根
     fx -----函数值
------------------------------------------------------*/
    imax:= 200
    tol:= 1e-8
    
    var tmp1,tmp2  float64
    var dx float64
    for i:=0;i < imax; i++ {
        tmp1 = funcX(x0)*dfuncX(x0)
        tmp2 = dfuncX(x0)*dfuncX(x0)-funcX(x0)*d2funcX(x0)
        x1 = x0 -tmp1/tmp2
        dx = math.Abs(x1-x0)
        if dx < tol {
            break
        }
        x0 = x1
        fmt.Printf("i= %4d  x= %12.7f  f(x)=%12.7f \n", i, x1, fx)
    }
    return
}