|
/* |
|
* @Author: Bai Shuai |
|
* @Date: 2014-05-11 20:42:29 |
|
* @Last Modified by: bai |
|
* @Last Modified time: 2014-05-31 22:47:42 |
|
*/ |
|
|
|
//非线性方程求根 |
|
//二分法、牛顿法、迭代法 |
|
//1. 求解非线性方程 |
|
//2. 研究迭代函数、迭代初值对函数收敛性及收敛速度的影响 |
|
|
|
/* 实验结果 |
|
迭代次数 1, 迭代值 0.0000000000 |
|
迭代次数 2, 迭代值 1.5000000000 |
|
迭代次数 3, 迭代值 0.7500000000 |
|
迭代次数 4, 迭代值 0.3750000000 |
|
迭代次数 5, 迭代值 0.1875000000 |
|
迭代次数 6, 迭代值 0.2812500000 |
|
迭代次数 7, 迭代值 0.3281250000 |
|
迭代次数 8, 迭代值 0.3515625000 |
|
迭代次数 9, 迭代值 0.3398437500 |
|
迭代次数 10, 迭代值 0.3457031250 |
|
迭代次数 11, 迭代值 0.3427734375 |
|
迭代次数 12, 迭代值 0.3442382812 |
|
迭代次数 13, 迭代值 0.3449707031 |
|
迭代次数 14, 迭代值 0.3453369141 |
|
迭代次数 15, 迭代值 0.3455200195 |
|
迭代次数 16, 迭代值 0.3456115723 |
|
迭代次数 17, 迭代值 0.3456573486 |
|
迭代次数 18, 迭代值 0.3456344604 |
|
迭代次数 19, 迭代值 0.3456230164 |
|
迭代次数 20, 迭代值 0.3456287384 |
|
迭代次数 21, 迭代值 0.3456258774 |
|
迭代次数 22, 迭代值 0.3456273079 |
|
迭代次数 23, 迭代值 0.3456280231 |
|
迭代次数 24, 迭代值 0.3456276655 |
|
-------------------我是分割线---------------- |
|
Newton迭代法, 初值0.0000000000 |
|
迭代次数 1, 迭代值 0.3333333333 |
|
迭代次数 2, 迭代值 0.3456790123 |
|
迭代次数 3, 迭代值 0.3456273932 |
|
-------------------我是分割线---------------- |
|
迭代法 初值 0.0000000000, 次数 10 |
|
迭代次数 1, 迭代值 0.7937005260 |
|
迭代次数 2, 迭代值 0.9643617579 |
|
迭代次数 3, 迭代值 0.9940246594 |
|
迭代次数 4, 迭代值 0.9990031165 |
|
迭代次数 5, 迭代值 0.9998338251 |
|
迭代次数 6, 迭代值 0.9999723034 |
|
迭代次数 7, 迭代值 0.9999953839 |
|
迭代次数 8, 迭代值 0.9999992306 |
|
迭代次数 9, 迭代值 0.9999998718 |
|
迭代次数 10, 迭代值 0.9999999786 |
|
-------------------我是分割线---------------- |
|
迭代法 初值 0.0000000000, 次数 10 |
|
迭代次数 1, 迭代值 -1.0000000000 |
|
迭代次数 2, 迭代值 -3.0000000000 |
|
迭代次数 3, 迭代值 -55.0000000000 |
|
迭代次数 4, 迭代值 -332751.0000000000 |
|
迭代次数 5, 迭代值 -73686529681121504.0000000000 |
|
迭代次数 6, 迭代值 -800192186653981478358652672830638575390678549790720.0000000000 |
|
迭代次数 7, 迭代值 -1024738174056893932527762049050938485592367730189188160409266654928227462101562808957796957393014967922717761885876347463950283744054040677931592393424896.0000000000 |
|
迭代次数 8, 迭代值 -Inf |
|
迭代次数 9, 迭代值 -Inf |
|
迭代次数 10, 迭代值 -Inf |
|
-------------------我是分割线---------------- |
|
Newton迭代法, 初值1.5000000000 |
|
迭代次数 1, 迭代值 1.3478260870 |
|
迭代次数 2, 迭代值 1.3252003990 |
|
迭代次数 3, 迭代值 1.3247181740 |
|
-------------------我是分割线---------------- |
|
Newton迭代法, 初值0.0000000000 |
|
迭代次数 1, 迭代值 -1.0000000000 |
|
迭代次数 2, 迭代值 -0.5000000000 |
|
迭代次数 3, 迭代值 -3.0000000000 |
|
迭代次数 4, 迭代值 -2.0384615385 |
|
迭代次数 5, 迭代值 -1.3902821472 |
|
迭代次数 6, 迭代值 -0.9116118977 |
|
迭代次数 7, 迭代值 -0.3450284967 |
|
迭代次数 8, 迭代值 -1.4277507040 |
|
迭代次数 9, 迭代值 -0.9424179125 |
|
迭代次数 10, 迭代值 -0.4049493572 |
|
迭代次数 11, 迭代值 -1.7069046452 |
|
迭代次数 12, 迭代值 -1.1557563611 |
|
迭代次数 13, 迭代值 -0.6941918133 |
|
迭代次数 14, 迭代值 0.7424942987 |
|
迭代次数 15, 迭代值 2.7812959407 |
|
迭代次数 16, 迭代值 1.9827252470 |
|
迭代次数 17, 迭代值 1.5369273798 |
|
迭代次数 18, 迭代值 1.3572624832 |
|
迭代次数 19, 迭代值 1.3256630944 |
|
迭代次数 20, 迭代值 1.3247187886 |
|
迭代次数 21, 迭代值 1.3247179572 |
|
*/ |
|
|
|
package main |
|
|
|
import ( |
|
"fmt" |
|
"math" |
|
) |
|
|
|
const ( |
|
accuracy = 1e-6 |
|
) |
|
|
|
func f1(x float64) float64 { |
|
return math.Pow(x, 3)*2 - math.Pow(x, 2) + 3*x - 1 |
|
} |
|
|
|
func df1(x float64) float64 { |
|
return math.Pow(x, 2)*6 - 2*x + 3 |
|
} |
|
|
|
// BinCalc 二分法解非线性方程 |
|
func BinCalc(left, right float64, f func(float64) float64, accu float64) { |
|
var mid, fa, fmid float64 |
|
var k int |
|
fa = f(left) |
|
// fb = f(right) |
|
for { |
|
mid = (left + right) / 2 |
|
fmid = f(mid) |
|
k++ |
|
fmt.Printf("迭代次数 %d, 迭代值 %.10f\n", k, mid) |
|
|
|
if right-left < accu { |
|
break |
|
} else { |
|
if fmid*fa < 0 { //fa的值不需要更新 |
|
right = mid |
|
} else { |
|
left = mid |
|
} |
|
} |
|
} |
|
} |
|
|
|
func iterf1(x float64) float64 { |
|
return math.Pow((x+1)/2, 1.0/3) |
|
} |
|
|
|
func iterf2(x float64) float64 { |
|
return math.Pow(x, 3)*2 - 1 |
|
} |
|
|
|
// Iteration 实现了不动点迭代法解非线性方程 |
|
func Iteration(init float64, f func(float64) float64, times int) { |
|
fmt.Printf("迭代法 初值 %.10f, 次数 %d\n", init, times) |
|
n := 0 |
|
for n < times { |
|
n++ |
|
init = f(init) |
|
fmt.Printf("迭代次数 %d, 迭代值 %.10f\n", n, init) |
|
} |
|
} |
|
|
|
func f2b(x float64) float64 { |
|
return math.Pow(x, 3) - x - 1 |
|
} |
|
|
|
func df2b(x float64) float64 { |
|
return math.Pow(x, 2)*3 - 1 |
|
} |
|
|
|
// Newton 实现了牛顿法解非线性方程 |
|
func Newton(init float64, f, df func(float64) float64, accu float64) { |
|
fmt.Printf("Newton迭代法, 初值%.10f\n", init) |
|
k := 0 |
|
xk, xk1 := init, init |
|
var fxk, dfxk, delta float64 |
|
fxk, dfxk = f(xk), df(xk) |
|
for { |
|
k++ |
|
xk = xk1 |
|
xk1 = xk - fxk/dfxk |
|
fmt.Printf("迭代次数 %d, 迭代值 %.10f\n", k, xk1) |
|
fxk = f(xk1) |
|
dfxk = df(xk1) |
|
|
|
//检查精度 |
|
if math.Abs(xk1) < 1 { |
|
delta = math.Abs(xk1 - xk) |
|
} else { |
|
delta = math.Abs((xk1 - xk) / xk1) |
|
} |
|
if delta < accu || math.Abs(fxk) < accu { |
|
break |
|
} |
|
} |
|
} |
|
|
|
// 打印实验信息 |
|
func init() { |
|
fmt.Println(`实验五-非线性方程求根 |
|
二分法、牛顿法、迭代法 |
|
1. 求解非线性方程 |
|
2. 研究迭代函数、迭代初值对函数收敛性及收敛速度的影响`) |
|
} |
|
|
|
func main() { |
|
BinCalc(-3.0, 3.0, f1, accuracy) |
|
fmt.Println("-------------------我是分割线----------------") |
|
Newton(0.0, f1, df1, accuracy) |
|
fmt.Println("-------------------我是分割线----------------") |
|
Iteration(0.0, iterf1, 10) |
|
fmt.Println("-------------------我是分割线----------------") |
|
Iteration(0.0, iterf2, 10) |
|
fmt.Println("-------------------我是分割线----------------") |
|
Newton(1.5, f2b, df2b, accuracy) |
|
fmt.Println("-------------------我是分割线----------------") |
|
Newton(0.0, f2b, df2b, accuracy) |
|
} |