VBA优化 - 具有多个args的函数

时间:2015-09-03 16:47:33

标签: vba optimization

您好我正在尝试创建一个函数,它将一些参数(与优化的变量无关)和一个我想要优化的变量作为输入。例如,对于foo_function(a,b,c,x),我想将a,b,c作为固定参数传递给foo_function,并通过更改x来查找foo_function的最小值。如果我能够在Matlab或Python中工作,这应该相对容易,因为函数可以返回另一个函数的句柄,但这在VBA中是不可能的。我试图使用http://www.quantcode.com/modules/mydownloads/singlefile.php?lid=424中的代码 有人知道如何继续吗?

1 个答案:

答案 0 :(得分:1)

您可以声明foo_function获取参数数组,如果只传递1个参数,则将其视为1个变量的函数,如果传递的参数大于1,则可以将参数存储在静态变量中。这允许您的调用代码在将其名称传递给优化代码之前设置foo_function的参数,优化代码将其视为1变量的函数。

作为概念证明,以下函数表示二次函数:

Function quad(ParamArray args()) As Double
    Dim x As Double
    Static a As Double
    Static b As Double
    Static c As Double

    If UBound(args) = 0 Then
        x = args(0)
    Else 'assumes that at least 3 parameters passed
        a = args(0)
        b = args(1)
        c = args(2)
        If UBound(args) = 3 Then
            x = args(3)
        Else
            Exit Function 'function call just initializes statics
        End If
    End If
    quad = a * x ^ 2 + b * x + c
End Function

当只传递1时,quad(x)只评估ax^2 + bx + c及其系数的当前值。如果传递了4,那么它被解释为对quad(a,b,c,x)的调用,具有明显的含义。如果只传递了3个参数,则会像sub:

一样调用它
quad a,b,c

并且不返回任何内容,只是将静态参数设置为传递的值。

为了测试它,我写了一个粗略的数值微分函数:

Function Derivative(f As String, x As Double, h As Double) As Double
    Derivative = (Application.Run(f, x + h) - Application.Run(f, x)) / h
End Function

这使用给定的步长近似于给定x值的f的导数。

以下测试子显示如何在将quad传递给派生函数之前设置Sub test() quad 1, 2, -3 'initializes quad to be x^2 + 2x - 3 Debug.Print Derivative("quad", 2, 0.0001) 'should be approximately 6 quad 3, 2, 1 Debug.Print Derivative("quad", 2, 0.0001) 'now around 14 End Sub

6.00010000001205 
14.0003000000277 

输出:

foo_function

另一方面,在某些方面更简单,方法是使用公共变量而不是var x11 = require('../../lib'); x11.createClient(function(err, display) { console.log('succesfully connected to \"' + display.vendor + '\" server'); console.log(display.client.QueryTree()); display.client.terminate(); }); 的参数的实际参数,这些参数与正在优化的变量无关。然后调用代码可以在优化之前分配给这些公共变量。这种方法将消除对参数数组的需要,但是具有使用全局类型变量的缺点,这些变量往往使程序不够模块化。