向 DenseVector 类型添加扩展时出现问题

Problems adding extension to DenseVector type

我正在尝试向 DenseVector class 添加一种方法,以便能够对向量进行 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?另外,我添加扩展方法的方式是否正确?

你的问题的原因是因为 extension method 为所有 Vector<'T> returns 定义了 GetSlice 方法 Vector<'T> 而不是 DenseVector.因此,如果您使用通过调用 GetSlice 工作的切片,您将获得一个 Vector 并且您上面的代码将无法按预期工作。

我不确定 MathNet 的内部结构是如何工作的,但您可以使用如下方法使您的扩展方法适用于所有 Vector<'T>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