【问题标题】:Problems adding extension to DenseVector type向 DenseVector 类型添加扩展时出现问题
【发布时间】:2016-10-01 17:05:57
【问题描述】:

我正在尝试向 DenseVector 类添加一个方法,以便能够对向量进行 n 次差分。以下似乎不起作用,因为类型推断抱怨 Vector 类型与 DenseVector 类型不兼容:

open System
open System.IO
open Deedle
open MathNet.Numerics
open MathNet.Numerics.LinearAlgebra
open MathNet.Numerics.LinearAlgebra.Double
open MathNet.Numerics.Distributions

[<Extension>]
type DenseVector with
    member this.diffVector (v : DenseVector) (n : int) =
        let rec run (v : DenseVector) (n : int) =
            match n with
            | 0 -> v
            | _ -> run (v.[ 1 .. v.Count-1 ] - v.[ 0 .. (v.Count-1)-1 ]) (n - 1)
        run v n

v.[ 0 .. (v.Count-1)-1 ] 在上面导致问题。为什么它被推断为 Vector 而不是 DenseVector 传递给函数的内容?另外,我添加扩展方法的方式正确吗?

【问题讨论】:

  • 你能在你的 repro 中包含你打开了哪些命名空间吗?
  • @Gustavo 我的测试表明他可能打开了MathNet.Numerics.LinearAlgebra.DoubleMathNet.Numerics.LinearAlgebra。他还拥有 MathNet 的 FSharp 扩展包。
  • 抱歉忘了包括这些。刚刚进行了编辑。

标签: f# mathnet-numerics


【解决方案1】:

您的问题的原因是因为为所有Vector&lt;'T&gt; 定义GetSlice 方法的extension method 返回Vector&lt;'T&gt; 而不是DenseVector。因此,如果您使用切片(通过调用GetSlice 来工作),您将获得一个 Vector,并且您的上述代码将无法按预期工作。

我不确定 MathNet 的内部是如何工作的,但您可以通过以下方式使您的扩展方法适用于所有 Vector&lt;'T&gt;s:

type Vector with
    member this.diffVector (v : Vector<'T>) (n : int) =
        let rec run (v : Vector<'T>) (n : int) =
            match n with
            | 0 -> v
            | _ -> run (v.[ 1 .. v.Count-1 ] - v.[ 0 .. (v.Count-1)-1 ]) (n - 1)
        run v n

或者,您可以通过类似的方式安全地从 Vector 向下转换为 DenseVector。这可能有效,也可能无效:

[<Extension>]
type DenseVector with
    member this.diffVector (v : DenseVector) (n : int) =
        let rec run (v : DenseVector) (n : int) =
            match n with
            | 0 -> v
            | _ -> let v1 = v.[ 1 .. v.Count-1 ] :?> DenseVector
                   let v2 = v.[ 0 .. (v.Count-1)-1 ] :?> DenseVector
                   run (v1 - v2) (n - 1)
        run v n

【讨论】:

  • 优秀。一个轻微的修改是创建一个静态成员。使用这种方式似乎更清洁。谢谢!
  • Math.NET Numerics API 已针对您始终在用户代码中使用通用基类的假设进行了优化(并且仅在您实际需要访问特定 DenseVector 成员时才向下转换)。所以我建议直接在泛型向量上编写这样的扩展方法,即这个答案中的第一个例子。
  • (也可以是Vector&lt;float&gt;
猜你喜欢
  • 1970-01-01
  • 2016-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 1970-01-01
相关资源
最近更新 更多