optimizationf#numerical-analysisilnumerics

F# and ILNumerics


I have just downloaded the last version of ILNumerics, to be used in my F# project. Is it possible to leverage on this library in F#? I have tried simple computations and it seems very cumbersome (in F#).

I would like to set up a constrained (or even unconstrained) optimization problem. The usual Rosenbrock function would do and then I will use my own function. I am having hard times in having even an Array being defined. The only kind of array I could define was a RetArray, for example with this code

let vector = ILMath.vector<float>(1.0, 2.0)

The compiler signals that vector is a RetArray; I think this is due to the fact that it is returning from a function (i.e.: ILMath.vector). If I define another similar vector, I can -e.g.- sum vectors, simply writing, for example

let a = ILMath.vector<float>(1.0, 2.0)
let b = ILMath.vector<float>(3.2,2.2)
let c = a  + b 

and I get

RetArray<float> = seq [4.2; 4.2]

but if I try to retrieve the value of c, again, writing, for example in FSI,

c;;

I get

Error: Object reference not set to an instance of an object.

What is the suggested way of using ILNumerics in F#? Is it possible to use the library natively in F# or I am forced to call my F# code from a C# library to use the whole ILNumerics library? Other than with the problem cited, I have problems in understanding the very basic logic of ILNumerics, when ported in F#.

For example, what would be the F# equivalent of the C# using scope as in the example code, as in:

using (ILScope.Enter(inData)) { ...

}

Solution

  • The reason that the second access of c fails is that ILNumerics is doing some very unusual memory management, which automatically releases the vector's memory when you might not expect it. In C#, this is managed via implicit conversion from vector to Array:

    // C#
    var A = vector<int>(1, 2, 3);          // bad!
    Array<int> A = vector<int>(1, 2, 3);   // good
    

    F# doesn't have implicit type conversions, but you can invoke the op_Implicit member manually, like this:

    open ILNumerics
    open type ILMath   // open static class - new feature in F# 5
    
    let inline (!) (x : RetArray<'t>) =
        Array<'t>.op_Implicit(x)
    
    [<EntryPoint>]
    let main argv =
        let a = !vector<float>(1.0, 2.0)
        let b = !vector<float>(3.2,2.2)
        let c = !(a  + b)
        printfn "%A" c
        printfn "%A" c
        0
    

    Note that I've created an inline helper function called ! to make this easier. Every time you create an ILNumerics vector in F#, you must call this function to convert it to an array. (It's ugly, I know, but I don't see an easier alternative.)

    To answer your last question, the equivalent F# code is:

    use _scope = Scope.Enter(inData)
    ...