2016-10-01 17 views
5

Próbuję dodać metodę do klasy DenseVector, aby móc odróżnić wektor n razy. Poniższa nie wydają się działać jako rodzaj wnioskowania skarży się, że typ Vector nie jest zgodny z typem DenseVector:Problemy z dodawaniem rozszerzenia do typu 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 ] w powyższym jest przyczyną problemów. Dlaczego jest on wywiedziony jako Vector, a nie DenseVector, co jest przekazywane do funkcji? Czy mój sposób dodania metody rozszerzenia jest poprawny?

+0

Czy możesz uwzględnić w swoim wydaniu, które przestrzenie nazw masz otwarte? – Gustavo

+0

@Gustavo Moje testy pokazują, że prawdopodobnie ma 'MathNet.Numerics.LinearAlgebra.Double' i ' MathNet.Numerics.LinearAlgebra' open. Ma także pakiet rozszerzeń FSharp dla MathNet. – Ringil

+0

Przepraszamy, nie uwzględniamy tych. Właśnie dokonałem edycji. –

Odpowiedz

3

Przyczyną problemu jest fakt, że extension method który definiuje metodę GetSlice dla wszystkich Vector<'T> zwraca nie Vector<'T>DenseVector. Więc jeśli używasz cięcia, które działa przez wywołanie GetSlice, otrzymasz Vector, a powyższy kod nie będzie działał zgodnie z oczekiwaniami.

nie jestem pewien, w jaki sposób wewnętrzne pracy MathNet, ale może po prostu być w stanie dokonać rozszerzenia metody pracy dla wszystkich Vector<'T> sz coś takiego:

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 

Alternatywnie, może się okazać, że możesz po prostu spuścić z Vector do DenseVector bezpiecznie przez coś takiego. To może, ale nie musi działać:

[<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 
+0

Doskonały. Jedną z niewielkich modyfikacji byłoby utworzenie statycznego elementu. Wydaje się nieco bardziej czysty w użyciu w ten sposób. Dziękuję Ci! –

+2

Interfejs Math.NET Numerics API jest zoptymalizowany pod kątem założenia, że ​​zawsze pracujesz z ogólnymi klasami bazowymi w kodzie użytkownika (i tylko downcast, jeśli rzeczywiście potrzebujesz dostępu do konkretnych elementów DenseVector). Polecam więc napisać taką metodę rozszerzenia bezpośrednio na generycznych wektorach, tj. Pierwszy przykład w tej odpowiedzi. –

+1

(może również być "Wektor ") –

Powiązane problemy