Fork me on GitHub
Source file: outer-product.fut

Computing outer products

The outer product of two arrays can be defined as follows:

def outer_prod op A B =
  map (\a -> map (\b -> a `op` b) B) A

This definition is parameterised over the multiplication operator. This allows us to obtain the “standard” outer product:

let std_outer_prod = outer_prod (f64.*)
> std_outer_prod [1.0f64, 2.0f64, 3.0f64] [4.0f64, 5.0f64, 6.0f64]
[[4.0f64, 5.0f64, 6.0f64],
[8.0f64, 10.0f64, 12.0f64],
[12.0f64, 15.0f64, 18.0f64]]

But we can also use to define matrix multiplication:

def dotprod A B =
  f64.sum (map2 (*) A B)

def matmul A B =
  outer_prod dotprod A (transpose B)
> matmul [[1.0f64, 2.0f64],
         [3.0f64, 4.0f64],
         [5.0f64, 6.0f64]] [[7.0f64, 8.0f64, 9.0f64],
                           [10.0f64, 11.0f64, 12.0f64]]
[[27.0f64, 30.0f64, 33.0f64],
[61.0f64, 68.0f64, 75.0f64],
[95.0f64, 106.0f64, 117.0f64]]