は、私は2つのリストを取る内積関数を記述:ドット製品機能
let inline dot a b =
List.zip a b
|> List.map (fun (a, b) -> a * b)
|> List.reduce (+)
はList.zip
を使用せずに、ドット積を計算するための良い方法はありますか?
は、私は2つのリストを取る内積関数を記述:ドット製品機能
let inline dot a b =
List.zip a b
|> List.map (fun (a, b) -> a * b)
|> List.reduce (+)
はList.zip
を使用せずに、ドット積を計算するための良い方法はありますか?
一つの短い方の方法は、List.map2
を使用することです:
let inline dot a b = List.map2 (*) a b |> List.sum
別List.fold2
を使用することです:
let inline dot a b = List.fold2 (fun state x y -> state + x * y) LanguagePrimitives.GenericZero a b
私はマトリクスでのF#でニューラルネットワークを行うための同じ必要性を持っていましたが、あなたおそらくベクトルを使用する可能性があります。
私はMathNet Numericsを使用しました。これには他の多くの機能があります。dot productです。
coreとF# extensionsの両方を取得してください。
あなたはニューラルネットワークをやっていると行列とのMathNetニューメリックスを使用する場合は、あなたはおそらくここSigmoid function
MathNet Raise Scalar by a Matrix
は、F#でMathNetニューメリックマトリックスを用いたニューラルネットワークに関連したバックプロパゲーションexampleあるでしょう。私はList.fold2
を使用して1が最速であると信じて3提案したものの中で
、:
let inline dot1 a b =
List.zip a b
|> List.map (fun (a, b) -> a * b)
|> List.reduce (+)
let inline dot2 a b = List.map2 (*) a b |> List.sum
// Modified with 0.0 instead of 0 and no 'inline'
let dot3 a b = List.fold2 (fun state x y -> state + x * y) 0.0 a b
let xs = [0.0..1000000.0]
> dot1 xs xs;;
Real: 00:00:00.242,
> dot2 xs xs;;
Real: 00:00:00.070
> dot3 xs xs;;
Real: 00:00:00.003
二つのリストをお越しは、おそらく非常に高価です。 map2-sum
ソリューションは高速ですが、リストを2回反復します。 fold2
ソリューションはリストを1回だけ通過します。
2番目の関数の 'inline'は' 0'が 'int '型の戻り値を持つようにしているので役に立ちません。 – Soldalma
'inline'が関数を一般化可能にする場合、' 0'の代わりに 'LanguagePrimitives.GenericZero'を使うと動作します。コンパイラに "ここで関数呼び出しを生成しない"と伝えるのであれば、それはそのままです。 – rmunn