我正在尝试在Excel上的VBA中创建一个使用正割方法收敛到单个根的代码。 x0
是第一个猜测,x1
是第二个猜测。出于某种原因,每次我将Secant_it
输入Excel单元格时,我都会#VALUE!
。我知道问题不在于Secant,因为当我将其输入单元格时,我得到第一个值的正确数字。我在这里做错了什么?
Function Secant(x0, x1)
Dim x_new As Double
x_new = x1 - f(x1) * (x1 - x0) / (f(x1) - f(x0))
Secant = x_new
End Function
Function Secant_it(x0, x1)
Dim x_new As Double
Dim j As Integer
j = 1
x_new = Secant(x0, x1)
While j < 21
x0 = x1
x1 = x_new
x_new = Secant(x0, x1)
j = j + 1
Wend
Secant_it = x_new
End Function
答案 0 :(得分:2)
我将您的功能更改为
Function Secant(x0, x1)
Dim x_new As Double
Dim a As Double, b As Double
a = f(x1)
b = f(x0)
x_new = x1 - a * (x1 - x0) / (a - b)
Secant = x_new
End Function
Function Secant_it(x0, x1)
Dim x_new As Double
Dim j As Integer
j = 1
x_new = Secant(x0, x1)
While j < 21
x0 = x1
x1 = x_new
x_new = Secant(x0, x1)
Debug.Print x_new
j = j + 1
Wend
Secant_it = x_new
End Function
Function f(x)
f = (Exp(x / 10) * Cos(x)) - (x ^ 2)
End Function
我注意到您收到了#VALUE!
,因为该函数在j = 9
之后中断,因为a
中的b
和Secant
变为0
。因此,0
除以Secant
函数会导致错误。
出于测试目的,我采用了=Secant_it(2,3)
答案 1 :(得分:0)
你的收敛测试导致溢出,因为在经过一定次数的迭代后,x0和x1变得非常接近,使得f(x1)-f(x0)太小。
您应该将收敛测试更改为检查x0和x1之间的差异是否低于所需的精度。
Function Secant_it(ByVal x0 As Double, ByVal x1 As Double)
Dim x_new As Double
Dim j As Integer
j = 1
x_new = Secant(x0, x1)
'While j < 21
While Abs(x1 - x0) > 0.000001 ' or any precision you desire
x0 = x1
x1 = x_new
x_new = Secant(x0, x1)
j = j + 1
Wend
Secant_it = x_new
End Function