F# 和 ILNumerics

如何解决F# 和 ILNumerics

我刚刚下载了 ilnumerics 的最新版本,可用于我的 F# 项目。是否可以在 F# 中利用这个库?我尝试过简单的计算,但看起来很麻烦(在 F# 中)。

我想设置一个有约束(甚至无约束)的优化问题。通常的 Rosenbrock 函数会做,然后我将使用我自己的函数。我什至很难定义一个数组。我可以定义的唯一类型的数组是 RetArray,例如使用此代码

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

编译器表示 vector 是一个 RetArray;我认为这是因为它是从函数返回的(即:ILMath.vector)。如果我定义另一个类似的向量,我可以 -e.g.- 求和向量,简单地写,例如

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

我明白了

RetArray<float> = seq [4.2; 4.2]

但是如果我尝试检索 c 的值,再次写入,例如在 FSI 中,

c;;

我明白

错误:未将对象引用设置为对象的实例。

在 F# 中使用 ilnumerics 的建议方法是什么?是否可以在 F# 中本地使用该库,或者我被迫从 C# 库调用我的 F# 代码以使用整个 ilnumerics 库?除了引用的问题之外,当我在 F# 中移植时,我在理解 ilnumerics 的基本逻辑方面存在问题。

例如,与示例代码中使用作用域的 C# 等效的 F# 是什么,如:

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

}

解决方法

只是详细说明 brianberns 的回答,您可以做一些事情来让自己更轻松。

我个人不会走定义自定义运算符的路线 - 尤其是 overrides an existing one 的那个。相反,也许您应该考虑使用 computation expression 来处理 ILMath 类型。这将允许您隐藏很多丑陋之处,在使用使用非 F# 标准(例如隐式类型转换)的库时会出现这种情况。

我无法访问 ILMath,因此我刚刚实现了这些虚拟替代方案,以便编译我的代码。我怀疑你应该能够不复制它,其余的代码将按预期工作

module ILMath =
    type RetArray<'t> = { Values: 't seq }

    and Array<'t> = { OtherValues: 't seq } with
        static member op_Implicit(x: RetArray<_>) = { OtherValues = x.Values }
        static member inline (+) (x1,x2) = { Values = (x1.OtherValues,x2.OtherValues) ||> Seq.map2 (+) }

type ILMath =
    static member vector<'t>([<ParamArray>] vs : 't []) = { ILMath.Values = vs }

如果您之前从未见过或实现过计算表达式,您应该查看我参考的文档。基本上,它以您决定的方式在一些丑陋之上添加了一些不错的语法糖。我的示例实现只添加了 let!(脱糖到 Bind)和 return(脱糖到 Return,duh)关键字。

type ILMathBuilder() =
    member __.Bind(x: ILMath.RetArray<'t>,f) =
        f(ILMath.Array<'t>.op_Implicit(x))
    member __.Return(x: ILMath.RetArray<'t>) =
        ILMath.Array<'t>.op_Implicit(x)

let ilmath = ILMathBuilder()

这应该在顶层定义和实例化(ilmath 变量)。这允许你写

let c = ilmath {
    let! a = vector(1.0,2.0)
    let! b = vector(3.2,2.2)
    return a + b
}

当然,这个实现只增加了对很少事情的支持,并且要求,例如,总是返回一个 RetArray<'t> 类型的值。根据文档扩展 ILMathBuilder 类型是从这里开始的方法。

,

第二次访问 c 失败的原因是 ILNumerics 正在做一些非常不寻常的内存管理,它会在您可能意想不到的时候自动 releases the vector's memory。在 C# 中,这是通过从 vectorArray 的隐式转换来管理的:

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

F# 没有隐式类型转换,但您可以手动调用 op_Implicit 成员,如下所示:

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

请注意,我创建了一个名为 ! 的内联辅助函数来简化此操作。每次在 F# 中创建 ILNumerics 向量时,都必须调用此函数将其转换为数组。 (我知道这很丑陋,但我认为没有更简单的替代方法。)

要回答您的最后一个问题,等效的 F# 代码是:

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?