2013-03-21 85 views
1

我试图解决数学公式中的三个变量。所述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,然后换了新的变量返回PARAMS。我尝试了一个代表ByRef参数(没有什么值得粘贴在这里的),但不能完全将新的变量值传递回主循环。我正在寻找关于如何在概念上完成思路的建议,或者有人从不同的角度来看它,并提出不同的范例。

回答

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