2016-10-01 2 views
5

Я пытаюсь добавить метод к классу DenseVector, чтобы иметь возможность разностно разделить вектор n раз. Далее, кажется, не работает, как определение типа жалуется, что тип Vector не совместим с типом DenseVector:Проблемы с добавлением расширения к DenseVector type

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 ] в выше вызывает проблемы. Почему это выводится как Вектор, а не DenseVector - это то, что передается функции? Кроме того, мой способ добавить метод расширения правильно?

+0

Можете ли вы включить в свой реестр, какие пространства имен у вас открыты? – Gustavo

+0

@Gustavo. Мои тесты показывают, что он, вероятно, имеет 'MathNet.Numerics.LinearAlgebra.Double' и ' MathNet.Numerics.LinearAlgebra'. И у него есть пакет расширения FSharp для MathNet. – Ringil

+0

Извините, забыл включить их. Просто сделал редактирование. –

ответ

3

Причина вашей проблемы потому, что extension method, который определяет метод GetSlice для всех Vector<'T> возвращает Vector<'T> не DenseVector. Поэтому, если вы используете срез, который работает, вызывая GetSlice, вы получите вектор, и ваш код выше не будет работать должным образом.

Я не уверен, как внутренности Mathnet работы, но вы можете просто быть в состоянии сделать свой метод расширения работы для всех Vector<'T> с чем-то вроде этого:

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

Отлично. Одна небольшая модификация заключалась бы в создании статического члена. Кажется немного более чистым, чтобы использовать этот путь. Спасибо! –

+2

API-интерфейс Math.NET Numerics оптимизирован для предположения, что вы всегда работаете с базовыми базовыми классами в коде пользователя (и только с отключением, если вам действительно нужно получить доступ к определенным членам DenseVector). Поэтому я бы рекомендовал написать метод расширения, подобный этому, на общих векторах напрямую, т. Е. Первый пример в этом ответе. –

+1

(также может быть 'Вектор ') –

Смежные вопросы