2016-10-01 17 views
5

DenseVectorクラスにメソッドを追加して、ベクトルをn回差異させようとしています。上記の問題を引き起こしている中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 ]:次は、型推論は、タイプがベクトル型DenseVectorと互換性がないと文句を言いよう動作するようには思えません。なぜそれがVectorに推論され、DenseVectorではなく、それが関数に渡されるのでしょうか?また、拡張メソッドを追加する私の方法は正しいですか?すべてVector<'T>ためGetSlice方法を定義extension methodVector<'T>ないDenseVector返しますので、あなたの問題のため

+0

開いている名前空間をreproに含めることはできますか? – Gustavo

+0

@Gustavo私のテストによれば、彼はおそらく 'MathNet.Numerics.LinearAlgebra.Double'と ' MathNet.Numerics.LinearAlgebra'を開いています。また、MathNet用のFSharp拡張パッケージも用意されています。 – Ringil

+0

申し訳ありませんが、それらを含めるのを忘れてしまった。ちょうど編集をしました。 –

答えて

3

理由があります。したがって、GetSliceを呼び出すことによって機能するスライシングを使用すると、Vectorが取得され、上記のコードは期待通りに機能しません。

私は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

Math.NET Numerics APIは、ユーザーコード内のジェネリックベースクラス(常に特定のDenseVectorメンバーにアクセスする必要がある場合はダウンキャストのみ)で動作するという前提で最適化されています。ですから、このような拡張メソッドをジェネリックベクターに直接書くことをお勧めします。つまり、この答えの最初の例です。 –

+1

( 'Vector 'でもかまいません) –

関連する問題