# `foldl` vs `foldr`: matrix multiplication order

#1

Sorry, but isn’t this suppose to give different results, namely `A*B` and `B*A` ???

``````julia> A = rand(3,3)
3x3 Array{Float64,2}:
0.601317  0.0789842  0.624138
0.3137    0.134492   0.600118
0.350883  0.306819   0.930303

julia> B = rand(3,3)
3x3 Array{Float64,2}:
0.87791    0.802677  0.691277
0.0102793  0.369752  0.0523712
0.628603   0.638735  0.980241

julia> foldl(*,[A,B])
3x3 Array{Float64,2}:
0.92105   0.910527  1.03162
0.654019  0.684845  0.812157
0.895989  0.98931   1.17055

julia> foldr(*,[A,B])
3x3 Array{Float64,2}:
0.92105   0.910527  1.03162
0.654019  0.684845  0.812157
0.895989  0.98931   1.17055
``````

The examples in the doc work (and expectedly give different results). Please help me see my mistake, I’m apparently blind!

#2

Ok, I just didn’t now what `foldl`/`foldr` are actually doing… I thought they fold a list from left or right but instead they seem to do (compare with example in doc):

``````julia> 2-(3-(4-(5)))
-2

julia> ((((2)-3)-4)-5)
-10
``````

And since matrix product is associative the result ist the same.

#3

Try with three matrices. These affect the order of association, not the order from left to right.

#4

@dpsanders thanks for your comment! However, three matrices don’t change the associativity of the matrix product.

#5

Ah, good point. Though floating point rounding errors could make a difference.

#6

They do fold from the left or right, traversing the list in different orders. But they do it by changing associativity, not by commuting terms. This is the standard terminology for “fold” operations.