Excel RK4 VBA函数的困难。函数只返回#REF!价值
不适用。不再是问题……试试这个:Excel RK4 VBA函数的困难。函数只返回#REF!价值,excel,vba,differential-equations,ref,runge-kutta,Excel,Vba,Differential Equations,Ref,Runge Kutta,不适用。不再是问题……试试这个: Function dCdt(y As Variant) As Variant dCdt = ((0.02) - (0.1) * (y)) End Function Function SIMRK44(ByVal x0 As Double, ByVal y0 As Double, ByVal n As Integer, ByVal xtarg As Double) As Double Dim k1 As Double, k2 As Double,
Function dCdt(y As Variant) As Variant
dCdt = ((0.02) - (0.1) * (y))
End Function
Function SIMRK44(ByVal x0 As Double, ByVal y0 As Double, ByVal n As Integer, ByVal xtarg As Double) As Double
Dim k1 As Double, k2 As Double, k3 As Double, k4 As Double
Dim ym As Double, ym2 As Double, ye As Double
Dim Slope As Double, yi As Double, xi As Double, h As Double
h = (xtarg - x0) / n
xi = x0
yi = y0
For i = 1 To n
'apply Euler Method to get y at the end of the interval
k1 = dCdt(yi)
ym = yi + k1 * h / 2#
k2 = dCdt(ym)
ym2 = yi + k2 * h / 2#
k3 = dCdt(ym2)
ye = yi + k3 * h
k4 = dCdt(ye)
Slope = (1 / 6#) * (k1 + 2# * k2 + 2# * k3 + k4)
yi = yi + Slope * h
xi = xi + h
Next i
SIMRK44 = yi
End Function
主要问题是名称RK44
指的是一个单元格,因此Excel会感到困惑。将函数重命名为SIMRK44
,问题就会消失
我对代码进行了调整,使其成为一个真实的模拟,其中每个步骤的结果取决于前一步。您的代码中出现了一些与不需要的yold
的混淆
为了更好的可读性,我使用了文字,每个值应该是一个实系数而不是整数。所以2
而不是2
。不管怎样,编译器在内部进行了更改,1/6
不是整数除法
此外,VBA默认将函数参数传递给ByRef
,这可能会导致副作用。必须在每个参数之前放置ByVal
,以向Excel显示函数不会修改参数。只有这样,它才能用作自定义项
如果我被要求编写一个
RK4
积分器,那么我会坚持使用教科书中给出的标准伪代码。更简单,更容易理解目的是什么
Function f(ByVal x As Double, ByVal y As Double) As Double
f = 0.02 - 0.1 * y
End Function
Function SIMRK4(ByVal x0 As Double, ByVal y0 As Double, ByVal n As Long, ByVal xtarg As Double) As Double
Dim xi As Double, yi As Double, h As Double
Dim k1 As Double, k2 As Double, k3 As Double, k4 As Double
h = (xtarg - x0) / n
xi = x0
yi = y0
Do
'Ensure we don't overstep
If xi + h > xtarg Then
h = xtarg - xi
End If
k1 = f(xi, yi)
k2 = f(xi + h / 2#, yi + h / 2# * k1)
k3 = f(xi + h / 2#, yi + h / 2# * k2)
k4 = f(xi + h, yi + h * k3)
xi = xi + h
yi = yi + (h / 6#) * (k1 + 2# * k2 + 2# * k3 + k4)
Loop Until xi = xtarg
SIMRK4 = yi
End Function
另外,上面的代码可以处理可变的时间步长,因为迭代次数不是固定的。要调试函数,请从VBA sub调用它,然后可以看到问题所在。如果您可以为RK44Lol提供示例参数,那么这也是非常有用的,主要问题是函数名!看看我的答案。