Files
sjy01-image-proc/vendor/github.com/nuknal/goNum/SearchByStep.go
2024-10-24 15:46:01 +08:00

98 lines
2.9 KiB
Go
Raw 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.

// goNum 是一个开源的go语言数值算法库[goNum is an open
// numerical library purely based on go programming language]
package goNum
// SearchByStep
/*
------------------------------------------------------
作者 : Black Ghost
日期 : 2018-10-31
版本 : 0.0.0
------------------------------------------------------
此程序设计使用搜索法来求解连续、单自变量函数指定有限区间
上的解
------------------------------------------------------
输入 :
fn 函数,定义为等式左侧部分,右侧为零
a, b 求解区间一般要求a<b但不严格
N 步数,区间细分粒度
tol 误差上限
输出 :
sol 解值
err 解出标志false-未全部解出true-全部解出
------------------------------------------------------
*/
import "math"
// SearchByStep 搜索法来求解连续、单自变量函数指定有限区间上的解
func SearchByStep(fn func(float64) float64, a, b float64,
N int, tol float64) ([]float64, bool) {
/*
搜索法来求解连续、单自变量函数指定有限区间上的解
输入 :
fn 函数,定义为等式左侧部分,右侧为零
a, b 求解区间一般要求a<b但不严格
N 步数,区间细分粒度
tol 误差上限
输出 :
sol 解值
err 解出标志false-未全部解出true-全部解出
*/
//初始化
ab0 := make([]float64, 0, 1000)
ab1 := make([]float64, 0, 1000)
sol := make([]float64, 0, 1000)
err := false
j := 0 //解的数量
h := (b - a) / float64(N) //搜索步长,应小于最近两解的距离
//确定单解区间,并存入对应数组
for i := 1; i < N+1; i++ {
if (fn(a+float64(i)*h) > 0 && fn(a+float64(i-1)*h) < 0) || (fn(a+float64(i)*h) < 0 && fn(a+float64(i-1)*h) > 0) {
ab0 = append(ab0, a+float64(i-1)*h)
ab1 = append(ab1, a+float64(i)*h)
sol = append(sol, (ab0[j]+ab1[j])/2.0)
j++
}
}
//单解区间内循环细化,直至精度满足要求
for i := 0; i < j; i++ {
Nn := 0 //死循环约束
solved := 0 //解得标志
for {
Nn += 1
//循环超过一定数
if Nn > 1000 {
err = false
return sol, err
}
h = (ab1[i] - ab0[i]) / float64(N)
for ii := 1; ii < N+1; ii++ {
if (fn(ab0[i]+float64(ii)*h) > 0 && fn(ab0[i]+float64(ii-1)*h) < 0) || (fn(ab0[i]+float64(ii)*h) < 0 && fn(ab0[i]+float64(ii-1)*h) > 0) {
ab0[i] = ab0[i] + float64(ii-1)*h
ab1[i] = ab0[i] + float64(ii)*h
//是否满足精度要求
if math.Abs(fn((ab0[i]+ab1[i])/2.0)) < tol {
sol[i] = (ab0[i] + ab1[i]) / 2.0
solved = 1
}
break //退出此区间的搜索循环
}
}
//如果解除此区间的解,则退出死循环
if solved == 1 {
break
}
}
}
//返回
err = true
return sol, err
}