多个变量的可重复使用的误差平方最小化函数

时间:2013-03-21 16:40:36

标签: vb.net lambda regression least-squares

我正在尝试用数学公式求解三个变量。 formula如下:

Dim secondMomentOfBeam As Func(Of Beamμ2params, Double, Double) =
    Function(params, z)
        Return params.σ0 ^ 2 + (params.M2 ^ 2) * Math.Pow(λ / (Math.PI * params.σ0), 2) * Math.Pow(z - params.z0, 2)
    End Function
使用

Friend Class Beamμ2params
    Public σ0 As Double
    Public z0 As Double
    Public M2 As Double

    Public Sub New(ByVal sigmaNot As Double, ByVal zNot As Double, ByVal Msquared As Double)
        Me.σ0 = sigmaNot
        Me.z0 = zNot
        Me.M2 = Msquared
    End Sub
End Class

我需要创建一个循环来抖动每个变量σ0,z0和M2,然后检查整体误差平方,然后重复或完成,具体取决于误差平方。

While errorSquared > 1
    ' minimize error with σ0 
    ' minimize error with z0 
    ' minimize error with M2 
End While

我没有为每个变量硬编码这个循环(并且有很多相同的代码块),而是希望有一个函数可以最小化任何变量,具体取决于lambda选择变量,如此

Dim minimizeErrorSquared As Func(Of Beamμ2params, Func(Of Beamμ2params, Double), Double, UInt32, Beamμ2params) =
    Function(params, selector, dither, iterations)
        ' dither value chosen by selector
        ' check error-squared
        ' dither toward zero
        ' up to max iterations
    End Function

selector,第二个参数,选择哪个变量将被抖动。这使我的循环现在看起来像

Dim params As New Beamμ2params(σ0initial, z0initial, M2initial)
While errorSquared > 1
    params = minimizeErrorSquared(params, Function(p As Beamμ2params) p.σ0, 0.01, 10)
    params = minimizeErrorSquared(params, Function(p As Beamμ2params) p.z0, 5, 10)
    params = minimizeErrorSquared(params, Function(p As Beamμ2params) p.M2, 0.05, 10)
    ' calculate error squared based on raw data and params
End While

我无法解决的问题是如何将新变量值应用于minimizeErrorSquared内的相应变量,然后返回更新了新变量的参数。我尝试了一个带有ByRef参数的委托(没有什么值得粘贴的),但是不能将新的变量值传递回主循环。我正在寻找关于如何在概念上完成我的思路的建议,或者从不同的角度来看待它并建议一个不同的范例。

1 个答案:

答案 0 :(得分:0)

这是一个解决方案,但是我不想要的解决方案。理想情况下,三个Func应该写成一个Func。寻找更好的解决方案

Dim minimizeErrorSquaredσ0 As Func(Of Beamμ2params, Double, UInt32, Beamμ2params) =
    Function(params, dither, iterations)
        ' minimize error-squared using params.σ0
    End Function

Dim minimizeErrorSquaredz0 As Func(Of Beamμ2params, Double, UInt32, Beamμ2params) =
    Function(params, dither, iterations)
        ' minimize error-squared using params.z0
    End Function

Dim minimizeErrorSquaredM2 As Func(Of Beamμ2params, Double, UInt32, Beamμ2params) =
    Function(params, dither, iterations)
        ' minimize error-squared using params.M2
    End Function

Try
    Dim errorSquared As Double = Double.MaxValue
    Dim params As New Beamμ2params(σ0initial, z0initial, M2initial)
    While errorSquared > 1
        params = minimizeErrorSquaredσ0(params, 0.01, 10)
        params = minimizeErrorSquaredz0(params, 5, 10)
        params = minimizeErrorSquaredM2(params, 0.1, 10)
        ' calculate error squared based on raw data and params
    End While
    Finally
End Try