我寫的點積函數,採用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 Numerics的處理矩陣,那麼你可能會想在Sigmoid function
MathNet Raise Scalar by a Matrix
這是關係到在F#中使用MathNet Numerics的矩陣神經網絡反向傳播example。
在這三個建議的人,我相信用List.fold2
一個是最快的:
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
解決方案更快,但在列表中迭代兩次。 fold2
解決方案只通過列表一次。
第二個函數中的'inline'不會幫助,因爲'0'強制它返回類型爲'int'。 – Soldalma
如果'inline'使該函數具有通用性,那麼使用'LanguagePrimitives.GenericZero'而不是'0'就可以工作。如果它只是告訴編譯器「不要在這裏生成一個函數調用」,那麼它現在很好。 – rmunn