在将C#转换为F#时处理byref和out params

时间:2017-01-22 00:25:27

标签: f# c#-to-f# alglib

有人可以帮助将以下C#示例代码从Alglib库转换为F#吗?我无法在互联网上找到任何关于如何从F#中使用它的例子。

        if world[i][j] == 255:

            if total > 3 or total < 2:
                newWorld[i][j] = 0

        elif total == 3:
                newWorld[i][j] = 255

这是我(差)尝试F#翻译:

        if world[i][j] == 255:

            if total > 3 or total < 2:
                newWorld[i][j] = 0

        else:

            if total == 3:
                newWorld[i][j] = 255

1 个答案:

答案 0 :(得分:3)

该库使用了大量byrefout参数,因此将其转换为F#并不简单,您需要正确处理它们:

#r @"C:\packages\alglibnet2\lib\alglibnet2.dll"

open System

let function1_grad(x : float [], func : float byref, grad : float [], obj_ : obj) =
    func <- 100.*System.Math.Pow(x.[0]+3.,4.) + System.Math.Pow(x.[1]-3., 4.)        
    grad.[0] <- 400.*System.Math.Pow(x.[0]+3. ,3.)
    grad.[1] <- 4.*System.Math.Pow(x.[1]-3. ,3.)

let runOptim() =

    let x = ref [|0.; 0.|]
    let epsg = 0.0000000001
    let epsf = 0.
    let epsx = 0.
    let stpmax = 0.1
    let maxits = 0

    let state = alglib.minlbfgscreate(1, !x)
    alglib.minlbfgssetcond(state, epsg, epsf, epsx, maxits)
    alglib.minlbfgssetstpmax(state, stpmax)
    alglib.minlbfgsoptimize(state, (fun a b c d -> function1_grad(a, &b, c, d)), null, null)
    let rep = alglib.minlbfgsresults(state, x)

    printfn "%s" (alglib.ap.format(!x, 2))

    let x = ref [|10.; 10.|]
    alglib.minlbfgsrestartfrom(state, !x)
    alglib.minlbfgsoptimize(state, (fun a b c d -> function1_grad(a, &b, c, d)), null, null)
    alglib.minlbfgsresults(state, x, ref rep)

    printfn "%i" rep.terminationtype
    printfn "%s" (alglib.ap.format(!x, 2))
    System.Console.ReadLine() |> ignore

我建议您阅读一下F#如何处理outbyref参数,例如,不要在声明中混淆refbyref并保留请注意,out参数可以被视为F#的附加tupled结果。

但我认为最棘手的部分是转换为带有byref参数的委托,您可以在this answer中阅读它。

请注意,您可以使用**运算符代替Math.Pow

func <- 100. * (x.[0]+3. ** 4.) + (x.[1]-3. ** 4.)
grad.[0] <- 400. * (x.[0]+3. ** 3.)
grad.[1] <- 4. * (x.[1]-3. ** 3.)