Files
goNum/OptimizeGS_test.go
Black Ghost e9ac846d52 update comments
update comments in all of files in convenient to generate package information using `godoc` command or give tips in LiteIDE editor when the cursor keeps resting on a function or method.
2019-03-01 10:13:34 +08:00

105 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// OptimizeGS_test
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2018-12-24
版本 : 0.0.0
------------------------------------------------------
黄金分割法(Golden Section)求单峰单自变量极小值
理论:
对于在区间[a, b]内有定义的凹函数f(x),取黄金分割点:
c = a+(1-r)(b-a)
d = b-(1-r)(b-a)
其中r为黄金分割比例(Sqrt(5)-1)/2
如果f(c) <= f(d)则将d赋予b继续迭代
如果f(c) > f(d)则将c赋予a继续迭代。
迭代终止条件为Abs(f(a)-f(b)) < tol取小值c或d
参考John H. Mathews and Kurtis D. Fink. Numerical
methods using MATLAB, 4th ed. Pearson
Education, 2004. ss 8.1.1.1
------------------------------------------------------
输入 :
fun 函数
a, b 区间范围
tol 控制误差
N 最大迭代步数
输出 :
sol 解
err 解出标志false-未解出或达到边界;
true-全部解出
------------------------------------------------------
*/
package goNum_test
import (
"math"
"testing"
"github.com/chfenger/goNum"
)
// OptimizeGS 黄金分割法(Golden Section)求单峰单自变量极小值
func OptimizeGS(fun func(float64) float64, a, b, tol float64, N int) (float64, bool) {
/*
黄金分割法(Golden Section)求单峰单自变量极小值
输入 :
fun 函数
a, b 区间范围
tol 控制误差
N 最大迭代步数
输出 :
sol 解
err 解出标志false-未解出或达到边界;
true-全部解出
*/
//判断a和b的关系
if math.Abs(fun(a)-fun(b)) < tol {
if fun(a) < fun(b) {
return a, true
} else {
return b, true
}
}
var sol float64
var err bool = false
r1 := 1.0 - (math.Sqrt(5.0)-1.0)/2.0 //1-r
for i := 0; i < N; i++ {
ba := b - a //b-a
c := a + r1*ba
d := b - r1*ba
//区间压缩
if fun(c) > fun(d) {
a = c
} else { //fun(c)<=fun(d)
b = d
}
//误差判断
if math.Abs(fun(a)-fun(b)) < tol {
err = true
if fun(c) < fun(d) {
sol = c
} else {
sol = d
}
return sol, err
}
}
return sol, err
}
func fun50(x float64) float64 {
return x*x - math.Sin(x)
}
func BenchmarkOptimizeGS(b *testing.B) {
for i := 0; i < b.N; i++ {
goNum.OptimizeGS(fun50, 0.0, 1.0, 1e-10, 1e3)
}
}