使用小增量查找4次多项式的x截距

时间:2016-05-18 03:25:47

标签: vba excel-vba excel

我试图通过递增x值来找到第4度函数的x截距。我觉得这种方式总是不起作用,并不是最有效的方法,我还有另一种方法吗?

我的代码是:

Sub Findintercept()
    Dim equation As Double, x As Double, A As Double, B As Double, C As Double, D As Double, E As Double
    A = 0.000200878
    B = -0.002203704
    C = 0.0086
    D = -0.02333
    E = 0.02033
    x = 0
    equation = A * x ^ 4 + B * x ^ 3 + C * x ^ 2 + D * x + E
    While (equation > 0.00001 Or equation < -0.00001)
        If (x > 5) Then
            MsgBox "Could not find intercept"
            equation = 0
        Else
            x = x + 0.0001
            equation = A * x ^ 4 + B * x ^ 3 + C * x ^ 2 + D * x + E
        End If
    Wend
    MsgBox x
End Sub

有时它无法在while循环中找到拦截因此IF条件。 (我总是希望截距小于5!

1 个答案:

答案 0 :(得分:3)

您的方法存在两个问题:

  1. 您假设步长可以更改x。步骤可能太大,导致您“超越”您正在寻找的价值。为了解决这个问题,你需要做一个小步长,这可能意味着需要过多的迭代才能找到解决方案。
  2. 您总是采用相同的方向来改变x。即使您的步长看似很小,您也可以“走过”解决方案,无法改变方向。或者,您最初的猜测可能是解决方案的错误方面,而您永远找不到答案。
  3. Newton-Raphson method整齐地处理这两个问题。您仍然需要选择与您正在寻找的根有些接近的初始猜测。

    这种方法确实存在潜在的问题,但是对于你正在处理的多项式,这是非常好的。

    下面是一个实现此方法的简单VBA子程序。它在4次迭代中解决了您的问题。我建议大量调整初始猜测(xii)以了解它如何影响你得到的解决方案。

    Sub SimpleNewtonRaphson()
    Const Tol As Double = 1E-06
    Const MaxIter As Long = 50
    Dim xi As Double, xii As Double, deriv As Double
    Dim IterCount As Long
    ' Initialize
        xi = 0#
        xii = 1#
        IterCount = 0
    
    ' Method
        Do While IterCount < MaxIter And Abs(xii - xi) > Tol
            xi = xii
            deriv = myDeriv(xi)
            If deriv = 0# Then Exit Do
            xii = xi - myFunc(xi) / deriv
            IterCount = IterCount + 1
        Loop
    
    ' Results
        If deriv = 0 Then MsgBox "Ran into a 0 derivative, modify initial guess"
        If IterCount >= MaxIter Then MsgBox "MaxIterations reached"
        If Abs(xii - xi) <= Tol Then MsgBox "Solution found @" & vbCrLf & "F(" & xii & ") = " & myFunc(xii)
    
    End Sub
    

    ...和你的等式的两个VBA函数,它的衍生物......

    Function myFunc(x As Double) As Double
    Const A As Double = 0.000200878
    Const B As Double = -0.002203704
    Const C As Double = 0.0086
    Const D As Double = -0.02333
    Const E = 0.02033
    
    myFunc = A * x ^ 4 + B * x ^ 3 + C * x ^ 2 + D * x + E
    
    End Function
    
    Function myDeriv(x As Double) As Double
    Const A As Double = 0.000200878
    Const B As Double = -0.002203704
    Const C As Double = 0.0086
    Const D As Double = -0.02333
    
    myDeriv = 4 * A * x ^ 3 + 3 * B * x ^ 2 + 2 * C * x + D
    
    End Function