我需要在闭包上使用牛顿方法。
Function f (x as Double, y as Double) as Double
f = x^3-y
End Function
我从一个单元格中获取y
的值,然后我想知道f
何时为零。在上面的玩具示例中,如果单元格包含y=8
,那么我希望Newton的方法能够找到接近x=2
的解法。
我的解决方案是制作newton_solve_f
函数:
Function newton_solve_f (y as Double as Double) as Double
Dim x as Double
x = 0 'initial guess for x
'do Newton's method to find x
...
newton_solve_f = x
End Function
因此,我将我的牛顿方法代码(taken from here)复制粘贴到newton_solve_f
。
问题在于我有几个这样的f
s(一些有两个以上的参数),如果我没有必须分开几乎相同的{{1}那么它会非常整洁对于他们每个人。
你如何在VBA中解决这个问题?
例如,在Python中,可以按如下方式解决此问题:
newton_solve_f
此处def f(y):
def g(x):
return x^3-y
return g
def newton_solve(f):
#do newton's method on f(x)
newton_solve(f(3))
是一个函数,一个变量的closure。 (维基百科上的闭包示例几乎与此相同。)
PS。我知道牛顿的方法也需要f(3)
的(部分)导数,我实际上做的更像是割线方法,但这与什么无关我问的是
答案 0 :(得分:1)
闭包不属于VBA。但是您可以在方法范围内使用静态变量。它们不能在方法之外使用。如果您希望变量在外部可见,则必须使用全局变量。优先在模块中声明它是公开的。
我们无法在VB中定义函数内部的函数。试图转换您提到的链接中给出的代码。我希望它对你有所帮助。不熟悉php,但你可以看到下面的方法,并相应地做出改变。
String#to_i!
答案 1 :(得分:0)
首先总结一下:你想要创建一个能找到(使用Newton-Raphson方法)函数根的函数。您已经编写了这些函数并且正在为某些函数工作,但是希望有助于扩展您的代码,以便它可以使用具有不同数量参数的各种函数吗?
我认为您首先需要考虑您希望它涵盖哪些输入功能。如果你只处理多项式(如你的例子所示),这应该是相当简单的。
你可以拥有以下的一般功能:
Function fnGeneralCase (x, y, z, w, a1, a2, a3, b1, b2, b3, c1, c2, c3 as Double) as Double
fnGeneralCase = a1*x^3 + a2*x^2 + a3*x + b1*y^3 + b2*y^2 + b3*y + c1*z^3 + c2*z^2 + c3*z + w
End Function
Function fnDerivGeneralCase (x, y, z, w, a1, a2, a3, b1, b2, b3, c1, c2, c3 as Double) as Double
fnDerivGeneralCase = a1*3*x^2 + a2*2*x + a3 + b1*3*y^2 + b2*2*y + b3 + c1*3*z^2 + c2*2*z + c3
End Function
当您不需要时,只需将输入设置为零(大部分时间都是如此)。
所以你的例子叫:
answer = fnGeneralCase(guess, 0, 0, -8, 1, 0, 0, 0, 0, 0, 0, 0, 0)
基本上给出了:
function = x^3-8
如果你想要包含多项式,那么这将变得更加复杂,但你仍然可以使用上述方法......
答案 2 :(得分:0)
这似乎是在提出2个相关问题:
不幸的是,这些都不是真正支持的,
e.g。
Public Function f(x as Double, y as Double) as Double
f = x^3-y
End Function
Function newton_solve_f (function_name as String, y as Double) as Double
Dim x as Double
x = 0 'initial guess for x
'do Newton's method to find x
...
' invoke function_name
x = Application.Run(function_name, x, y)
...
newton_solve_f = x
End Function
假设f在名为' Module1'的模块中。你可以用这个来打电话:
x = newton_solve('Module1.f', 3)
请注意,您要呼叫的功能必须是公开的。