I write a dot product function that takes 2 lists:
let inline dot a b =
List.zip a b
|> List.map (fun (a, b) -> a * b)
|> List.reduce (+)
Is there a better way to calculate dot product without using List.zip
?
One shorter way would be to use List.map2
:
let inline dot a b = List.map2 (*) a b |> List.sum
Another would be to use List.fold2
:
let inline dot a b = List.fold2 (fun state x y -> state + x * y) LanguagePrimitives.GenericZero a b
I had the same need for doing neural networks with F# with matrixes, but you could probably use Vectors.
I used MathNet Numerics which has among many other functions dot product.
Make sure you get both the core and the F# extensions.
If you are doing neural networks and will use MathNet Numerics with Matrices then you will probably want the Sigmoid function
MathNet Raise Scalar by a Matrix
Here is a backpropagation example related to neural networks using MathNet Numerics matrix in F#.
Among the three proposed ones, I believe the one using List.fold2
is the fastest:
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
Zipping the two lists is probably quite expensive. The map2-sum
solution is faster but iterates twice through the list. The fold2
solution only goes once through the list.